Android系统随着智能终端设备的发展在全球广泛普及, 根据调查报告显示, 截止2016年第四季度, Android的市场占有率已达到81.7%[1]. 在其高速发展的同时也带来了严重的问题, 大量恶意apk在互联网上流行, 据360互联网安全中心统计, 2016年全年, 360互联网安全中心累计截获Android平台新增恶意程序样本1403.3万个, 平均每天新增3.8万恶意程序样本[2]. 恶意apk的一些行为例如盗取隐私信息、锁屏勒索等, 对用户的利益造成损害, 使得恶意apk的检测尤为重要.
目前, Android平台恶意代码检测已展开广泛的研究, 主要思想方法是直接由桌面平台移植到移动平台, 再根据Android平台的一些特点加以改进, 主要技术可划分为静态检测与动态检测[3], 两种方法各有优劣, 本文将研究静态检测.
现今主流方法是在提取出apk的各种特征后通过一些机器学习算法对已知样本进行学习形成分类器, 再对未知样本进行分类[4]. 权限信息作为Android软件的典型静态型特征, 在恶意apk检测方面得到广泛的应用. 文献[5]通过对权限进行聚类去冗余得到相互独立并相关性强的特征集合, 再通过改进的朴素贝叶斯算法进行分类; 文献[6]以窃取用户隐私数据为切入点, 提炼出对隐私资源十分敏感的权限组合, 并实现了一种专门针对窃取隐私的恶意应用的检测方法. 但若恶意apk制作者故意对权限进行混淆, 仅以权限作为特征拥有明显的不足性, 除了权限特征, apk的API调用与系统调用也是重要的特征.
恶意apk不仅拥有静态特征, 还拥有许多运行时的动态特征. 对此, 文献[7]指出了现阶段大部分检测技术的不足和缺陷, 并从安装、激活等特征入手, 研究各种动态恶意行为, 例如路过式下载、软件升级、权限提升; Padriya[8]等人研究了恶意软件的各种行为特征和静态特征, 并探讨了各种检测方法. 针对各种动态特征, 孙润康[9]等人以行为特征为基础实现了一种Android软件行为的动态检测框架, 并采用SVM、朴素贝叶斯等多种基本分类算法验证了其有效性; Luoxu Min[10]等人也提出了基于运行时行为的动态检测方法并且结合了静态分析技术与反编译技术. 可以看出大多方法通常采用朴素贝叶斯, k近邻等基本算法, 而某一特定算法未必适合此时所选用的特征数据, 因此具有一定局限性. 文献[11]提出了一种充分考虑Android应用多类特征的三层混合系综算法, 获取apk的各种动态特征与静态特征, 对不同种类特征在不同层面采用不同的分类算法, 对apk进行综合评判, 提高了检测准确率, 但其特征的提取过程和算法的实现过程都较为繁琐, 增加了时间成本和计算机资源的消耗.
针对以上方法的局限性, 本文提出了一种基于多特征和Stacking算法的Android恶意软件静态检测方法. 作者选取权限、API、SO库作为特征, 这些特征能够明显反映apk的恶意倾向, 并且作为静态特征提取较为容易, 缩短特征提取的时间, 将它们进行组合, 在保证特征向量有效的情况下降低计算的复杂度; 在机器学习阶段运用Stacking集成学习算法将多个弱学习器组合后形成强学习器提高识别准确率.
1 Android平台机制简述Android系统架构主要分为四个层面: 应用程序层, 应用程序框架层, 系统运行库层, Linux内核层, 如图1所示, Android程序由Java语言编写并经过编译后生成Dex可执行文件, 以字节码的形式在Dalvik虚拟机中运行. 每一个进程都拥有自己的虚拟环境, 不同进程是相互隔离的, 以此保障系统的安全性. 权限机制是Android精心构建的一项安全机制, 若应用程序要进行一些敏感操作和需要某些特权时, 比如访问或使用系统的文件、手机的硬件资源都必须要在AndroidManifest.xml配置文件中声明相应的权限[12], 并且在安装时提醒用户程序所使用的权限, 让用户自行判断, Android官网共列出了所有可使用的137种权限[13]. 为了满足Android平台下一些软件的复杂功能, 凭借Java语言的JNI特性Google向开发者提供了Android NDK. 开发者可以使用C与C++编写SO动态链接库让Java程序直接调用, 这一方法提高了一些程序的运行效率, 并且使软件的跨平台性得到提高. 另一方面复杂的C/C++代码让破解者难以反编译, 使用它进行apk的加密混淆效果更好, 增强了Android软件的安全性.
2 检测算法 2.1 检测算法框架检测算法的整体框架如图2所示,
(1) 首先分别提取所有训练样本权限、API、SO库三种不同特征.
(2) 对获得的所有特征进行卡方检验去除与判断是否为恶意软件无关的特征, 得到强相关性特征集合.
(3) 针对每个apk, 将其特征中的强相关性组合为特征向量.
(4) 在分类器训练过程中采用Logistic, SVM, kNN作为初级分类器, CART决策树作为次级分类器实现Stacking算法, 并通过特征向量数据训练成最终分类器.
(5) 运用测试样本验证算法性能.
2.2 检测算法框架 2.2.1 特征提取本文的方法使用了apk文件中的权限申明信息, API使用信息, SO库的使用情况, 各特征提取方式如下:
1) 谷歌Android官网共申明了137种权限, 使用SDK中集成的工具aapt可提取apk中的权限信息.
2) API调用信息的提取利用baksmali对apk文件中的classes.dex进行反编译得到smali文件, 再对所有的smali文件进行扫描, 即可获得样本的API调用集合.
3) SO文件存在于apk包中lib目录下, 直接对apk解压后提取.
2.2.2 特征选取
从apk中提取的这些特征并不是都可利用于对恶意软件的识别, 某些特征无论是正常软件还是恶意软件都会频繁出现, 故其中存在着大量的冗余, 必须去除一些与识别恶意软件无关的特征, 降低无关特征对识别的影响和计算的复杂性.
皮尔森卡方检验是由Pearson提出的一种假设检验方法, 可用于独立性检验, 即验证两个变量是否相互独立. 我们选用基本的四格卡方检验, 其公式如下:
${\chi ^2} = \frac{{{{(ad - bc)}^2} \times N}}{{(a + b)(c + d)(a + c)(b + d)}}$ | (1) |
在式(1)中a, b, c, d分别代表拥有某特征是恶意软件, 拥有某特征非恶意软件, 无某特征是恶意软件和无某特征非恶意软件这四种情况的频数, N代表总的频数. 针对样本中的所出现的所有特征, 都利用式(1)进行计算其卡方值, 卡方值越大则表明该特征与是否为恶意软件有较强相关性, 根据某一阈值即可筛选出合适的特征, 剔除冗余的特征.
2.2.3 特征的组合针对每一个样本只获取卡方检验后得到的特征集合中的特征, 可将权限的特征向量定义为(a1, a2,…,ah), 若该样本拥有k特征, 则ak = 1, 否则ak=0. 同理将API特征向量定义为(b1, b2,…, bi), SO库信息特征向量定义为(c1, c2,…, cj), 然后简单组合为x = (a1, a2,…, ah, b1, b2,…, bi, c1, c2, … ,cj), 这种简单组合在一定程度上可降低分类器学习与测试时计算的复杂度.
2.3 分类算法Stacking算法是由Wolpert于1992年提出的一种集成学习算法, 又称为Stacked generalization[14–16]. 相比于Bagging与Boosting在较多情况下采用相同的分类算法训练个体学习器, Stacking算法结合多个不同的分类算法, 可看做一种特殊的结合策略. Stacking算法主要分为两层, 将第0层的学习器称为初级学习器, 而将第1层用于结合的学习器称为次级学习器. 先通过原始的特征数据作为输入训练出多个初级学习器, 在将初级学习器的输出作为特征用于训练出次级学习器, 如图3所示.
具体方法如下:
在初级学习阶段使用k折交叉检验方法[17]训练各学习器. 即将初始训练数据集T = ((x1, s1), (x2, s2),…, (xh, sh))划分成k个大小相似的子数据集T1, T2,…, Tk, 将T–Tj作为m学习算法的训练数据并得到学习器Lmj, 然后将Tj作为测试数据输入Lmj. 对每一个子数据集都用m学习算法进行此操作, 最后每一个样本都会得到测试并输出结果yim. 若共有n个学习算法, 训练结束后对每一个样本xi, 都会产生n个结果, 由它们组成新的特征向量yi = (yi1, yi2,…, yin)作为次级学习器的训练数据, 标记依然为原标记si.
本文所实现的Stacking算法的初级学习器采用Logistic回归, 支持向量机, k-近邻作为分类算法, CART决策树作为次级学习器的分类算法. 伪代码描述:
Input: 初始训练集T = ((x1, s1), (x2, s2),…, (xh,sh)), 初级学习算法Logistic(), SVM(), kNN(), 次级学习算法CART(), 交叉检验子集数k
T1, T2,…, Tk = k_Fold(T, k)
Meta_T = {}
FOR EACH Tj in {T1, T2,…, Tj}:
LogisticClf[j] = Logistic(T – Tj)
SVMClf[j] = SVM(T – Tj)
kNNClf[j] = kNN(T – Tj)
FOR EACH xi in Tj:
yi1= LogisticClf[j].predict(xi)
yi2= SVMClf[j].predict(xi)
yi3= kNNClf[j].predict(xi)
Meta_T.append(((yi1,yi2, yi3), si))
END FOR
END FOR
CARTClf = CART(Meta_T)
Output: 初级分类器LogisticClf, SVMClf, kNNClf与次级分类器CARTClf
2.4 学习器的测试在学习器的训练过程中, 每一种分类算法都生成了k个分类器, 测试过程中根据投票法决定该算法分类结果. 即使用这k个分类器都对测试样本进行分类, 对可能产生的结果进行投票, 本实验中只有Normal与Virus两种结果, 最后若Normal票数更多, 则该分类算法分类结果为Normal, 否则为Virus. 将LogisticClf, SVMClf, KNNClf的分类结果组合(yi1, yi2, yi3)作为新的向量输入次级学习器CARTClf进行分类取得最终结果.
3 实验结果作者首先分别从VirusShare[18]和安卓市场获取了2460份恶意apk样本与2659份正常apk样本, 并将其中1460份恶意样本与1659份正常样本作为训练样本
在实验中进行反复测试后将三种特征的阈值分别定位60、800和20, 最后统计得到53种权限, 238种API, 94种SO库, 如表1所示.
本实验使用TP代表正常样本判断正确数, FN代表正常样本判断错误数, TN代表恶意样本判断正确数, FP代表恶意样本判断错误数. 定义以下指标:
准确率:
$ACC = \frac{{TP + TN}}{{TP + TN + FP + FN}}$ | (2) |
从图4可以看出, 在使用单种特征的情况下, Stacking算法相比于其它单个算法有所提高. 另外可以看出由于SO库并不是所有的apk都使用, 所以检测率较低, 在实验中作为辅助特征.
结合图4与图5, 在使用多特征后, 各种检测算法的检测率都有一定提升, 并且Stacking算法最为突出, 准确率达到94.05%, 对恶意软件有较好的识别能力.
4 结语本文提出了一种多特征结合与Stacking算法组合多个基本分类算法的恶意软件检测方法. 从apk中获得多种权限, 并去除其中的冗余特征, 再将它们组合为一个特征向量; 选择Logistic、SVM和kNN分别作为Stacking算法的初级学习算法, 将经过它们分类后的输出结果组合为特征向量输入使用CART算法的次级学习器进行判断. 实验结果表明本文提出的分类方法具有较强的检测能力. 该方法的不足之处在于相比其它简单的算法, 检测速率稍低, 下一步的研究将改善分类的各环节, 提高分类的速度.
[1] |
Gartner. Gartner says worldwide sales of smartphones grew 7 percent in the fourth quarter of 2016. http://www.gartner.com/newsroom/id/36098. [2017-02-15].
|
[2] |
360互联网安全中心. 2016年中国手机安全状况报告. http://zt.360.cn/1101061855.php?dtid=1101061451&did=490260073. [2017-02-06].
|
[3] |
卿斯汉. Android安全研究进展. 软件学报, 2016, 27(1): 45-71. DOI:10.13328/j.cnki.jos.004914 |
[4] |
Amos B, Turner H, White J. Applying machine learning classifiers to dynamic: Android malware detection at scale. 2013 9th International Wireless Communications and Mobile Computing Conference. Sardinia, Italy. 2013. 1666–1671.
|
[5] |
张锐, 杨吉云. 基于权限相关性的Android 恶意软件检测. 计算机应用, 2014, 34(5): 1322-1325. DOI:10.11772/j.issn.1001-9081.2014.05.1322 |
[6] |
黄海根, 曾云科. 基于权限组合的Android窃取隐私恶意应用检测方法. 计算机应用与软件, 2016, 33(9): 320-323, 333. |
[7] |
边悦, 戴航, 慕德俊. Android恶意软件特征研究. 计算机技术与发展, 2014, 24(11): 178-181. |
[8] |
Padriya N, Mistry N. Review of behavior malware analysis for android. International Journal of Engineering and Innovative Technology (IJEIT), 2013, 2(7): 230-232. |
[9] |
孙润康, 彭国军, 李晶雯, 等. 基于行为的Android恶意软件判定方法及其有效性. 计算机应用, 2016, 36(4): 973-978. DOI:10.11772/j.issn.1001-9081.2016.04.0973 |
[10] |
Min LX, Cao QH. Runtime-based behavior dynamic analysis system for android malware detection. Advanced Materials Research, 2013, 756-759: 2220-2225. DOI:10.4028/www.scientific.net/AMR.756-759 |
[11] |
杨欢, 张玉清, 胡予濮, 等. 基于多类特征的Android应用恶意行为检测系统. 计算机学报, 2014, 37(1): 15-27. |
[12] |
Enck W, Ongtang M, McDaniel P. Understanding android security. IEEE Security & Privacy, 2009, 7(1): 50-57. |
[13] |
Google. Manifest permission. https://developer.android.com/reference/android/Manifest.permission.html. [2017-02-10].
|
[14] |
Wolpert DH. Stacked generalization. Neural Networks, 1992, 5(2): 241-259. DOI:10.1016/S0893-6080(05)80023-1 |
[15] |
Zhou ZH. Ensemble Methods: Foundations and Algorithms. Boca Raton, FL: Chapman and Hall/CRC, 2012.
|
[16] |
周星, 丁立新, 万润泽, 等. 分类器集成算法研究. 武汉大学学报(理学版), 2015, 61(6): 503-508. |
[17] |
李航. 统计学习方法. 北京: 清华大学出版社, 2012.
|
[18] |
VirusShare.com. Because sharing is caring. http://virusshare.com/support. [2017-02-01].
|