目录
摘要
如今,Android恶意软件带来的安全风险日益增加。机器学习被认为是提高恶意软件检测性能的潜在解决方案。对于基于机器学习的 Android 恶意软件检测,特征提取起着关键作用。考虑到应用程序的源代码与文本文档具有可比性,我们提出了一种基于主题模型的新的Android恶意软件检测方法,这是一种有效的文本特征提取技术。我们的方法将应用程序的反编译代码视为文本文档,并使用主题模型来挖掘代码中能够反映应用程序语义特征的潜在主题。实验结果表明,我们的方法比最先进的方法表现更好。此外,我们的方法自动挖掘应用程序文件中的特征,无需手动设计,因此克服了现有方法依赖专家先验知识的限制。
介绍
自2008年推出第一款Android智能手机HTC Dream以来,Android设备呈指数级增长。同时Android应用程序的数量也迅速增加,带来了众多的安全漏洞和恶意攻击。根据360实验室的报告[1],2018年新增Android恶意软件样本434.2万个,平均每天增长1.2万个。因此,寻找有效且高效的Android恶意软件检测方法非常重要。目前Android恶意软件检测的研究根据分析过程中是否执行代码可以分为静态分析方法和动态分析方法。静态分析方法无需运行代码,通过逆向工程获取源代码,提取源代码的不同特征;提取特征的方法包括词法分析、语法分析、控制流分析、数据流分析等。动态分析方法在沙箱或虚拟机等虚拟环境中运行代码,通过触发器记录应用程序的行为,并利用行为信息提取特征进行分类或检测。目前,许多研究采用静态分析来检测Android恶意软件。王等人。 [2]使用特征排序的方法对Android权限的风险进行排序,并使用机器学习模型来检测恶意软件。阿弗等人。 [3] 提出了 DroidAPIMiner 来挖掘用于 Android 恶意软件检测的强大 API 功能。阿里·费佐拉等人。 [4] 评估了 Android Intent 作为一项显着功能的有效性。 LeakMiner [5]、TrustDroid [6]、FlowDroid [7]、DidFail [8] 是从数据流中提取特征进行检测的方法。杨等人。 [9] 提出了 Droidminer,它挖掘来自相同恶意软件家族的应用程序的控制流图中的共同结构和属性。在动态分析中,Asaf 等人。 [10]提出DroidHunter通过监控关键的Android运行时API来检测恶意代码的加载。徐等人。 [11] 提出了 FLEXDROID,它在 Android 应用程序清单中实现了一个附加组件。该组件允许开发人员设置本地代码的权限。阿丰索等人。 [12]提出了Going Native,它为本地代码生成策略来限制恶意行为。由于应用程序不被执行,静态分析方法更加高效,适合海量的Android恶意软件检测任务。这类分析方法依赖于不同的特征,如权限、API、Intent、数据流分析、控制流图等,代表了不同的分析视角。不同的特征将导致对 Android 代码的不同关注以及对不同类型数据集的不同准确度。因此,提取有效且全面的语义特征对于提高检测性能非常重要。数据流分析和控制流图分析等特征提取方法基于专家的先验知识。本文提出了一种新的Android应用程序特征提取方法。我们使用主题模型来挖掘Android应用程序反编译源代码中潜在的主题信息。主题模型是一种统计模型,用于在大量文档中发现潜在主题,该模型可以通过统计单词数来自动分析文档。主题模型根据统计数据判断文档中的主题以及每个主题所占的比例,从而挖掘文本的深层隐含语义信息。本文将反编译后的代码视为文档,利用主题模型挖掘潜在主题。主题模型可以尽可能减少源代码中信息的丢失。该方法能够克服现有方法中手工设计的局限性,能够自动挖掘最能代表应用特征的信息。本文的主要贡献在于,提出了一种基于主题模型的Android恶意软件检测方法,并且该方法取得了良好的检测效果。该方法采用了特征提取的新视角。将Android应用程序的反编译代码视为文本文档,利用主题模型挖掘潜在的主题信息,用于Android恶意软件检测。该方法与两个公共数据集 Drebin [13]、AMD [14] 和一个自行收集的数据集上最先进的方法进行了比较。三个数据集的大小分别为15121、19561和14566。准确率高达99.9%,并且我们的方法在假阴性率和假阳性率上表现更好,这证明了基于主题模型的特征提取方法的有效性。本文的其余部分组织如下。第 2 节重点介绍了相关工作。第 3 节介绍了我们基于主题模型的方法。第 4 节介绍实验并分析结果。第 5 节总结了本文。
相关工作
目前Android恶意软件检测的研究可分为静态分析方法和动态分析方法。静态分析方法主要通过逆向工程提取静态特征。王等人。 [2]研究了Android应用程序中的权限风险。他们采用特征排序的方法对Android权限的风险进行排序,并利用机器学习模型(包括SVM、逻辑回归、决策树、随机森林等)检测恶意软件。实验结果达到了94.62%的准确率。阿弗等人。 [3]提出了DroidAPIMiner,它根据数据集中API的概率分布提取具有高风险和独特性的API集合。并且他们进一步提取了API相关的包信息和权限信息来丰富功能。岑等人。 [15]从反编译的源代码中提取API调用和权限信息作为组合特征,并使用概率判别模型来检测Android恶意软件。他们通过应用特征选择来提高分类效果。阿里·费佐拉等人。 [4] 评估了 Android Intent 作为恶意软件检测的显着特征的有效性。实验结果表明,Intent在描述恶意代码意图时丰富了语义信息。不过,研究也强调,Intent特征并不是最终的解决方案,而应该与其他已知的有效特征结合使用。数据流分析也称为污点分析,跟踪程序内的数据流,以发现潜在的、可疑的数据泄露路径。数据流分析定义了两个概念,即源和汇。 Source是获取敏感数据的位置,Sink是敏感数据泄露的位置。通过污点跟踪,数据流分析可以找出是否存在从源到接收器的路径。目前最流行的数据流分析工具包括Yang等人提出的LeakMiner。 [5],Zhao等人提出的TrustDroid。 [6],Arzt等人提出的FlowDroid。 [7] 和 Burket 等人提出的 DidFail。 [8]。杨等人。 [9] 提出了 Droidminer,它挖掘来自相同恶意软件家族的应用程序的控制流图中的共同结构和属性。姚等人。 [16]将社区发现算法应用于函数调用图。对于Android应用程序的函数调用图,计算每个函数节点的风险权重,并将其定义为节点的属性。周等人。 [17]对敏感API列表中的每个API提取子图,并根据恶意软件家族样本获得最大同构子图。纳拉亚南等人。 [18]提出了一种基于多视图学习的Android恶意软件检测方法。他们根据不同的特征生成不同类型的子图,包括API子图、数据流子图、权限子图、指令序列子图等。然后他们为每个子图学习了一个图内核,并使用多核SVM作为分类器。静态分析方法可以覆盖程序执行的所有可能路径。然而,这些方法很容易受到代码混淆的影响。动态分析方法在虚拟环境中运行代码并观察 Android 应用程序的行为。阿萨夫等人。 [10]提出DroidHunter通过监控关键的Android运行时API来检测恶意代码的加载。徐等人。 [11] 提出了 FLEXDROID,它在 Android 应用程序清单中实现了一个附加组件。该组件允许开发人员设置本地代码的权限。阿丰索等人。 [12]提出了Going Native,为本地代码生成策略来限制恶意行为。此外,还提出了多种用于Android恶意软件检测的动态监控工具。 Droidbox [19] 和 Droidmon [20] 都是基于 Android 运行时仪器变化的动态监控工具。动态分析方法的缺点在于其代码覆盖率有限,即无法覆盖应用程序的所有执行路径。此外,动态分析方法的时间复杂度较高,无法满足大规模Android恶意软件检测的效率要求。
3 方法
3.1 概述
现有的静态检测方法从权限、API、函数调用图、控制流图和数据流分析中提取特征。这些观察视角基于专家的先验知识,这在某些情况下是严格的要求。本文提出一种基于主题模型的Android应用特征提取方法,挖掘反编译代码中潜在的主题信息进行检测。
主题模型认为文档在生成时以一定的概率选择一个或多个主题,每个主题以一定的概率选择一个或多个单词。我们的方法将 Android 应用程序的反编译代码视为文档。并应用主题模型挖掘大量应用样本中潜在的主题信息。主题模型提取的主题向量用作应用程序的特征来训练机器学习模型进行检测。
在反编译APK文件获取源代码时,我们选择获取Java源代码而不是smali源代码。原因是当表达相同的语义时,smali代码量比Java代码量要大得多。此外,第三方库在Android应用程序中也被广泛使用。这些代码通常不是恶意的,并且不表征应用程序的特定行为。因此,在进行后续分析之前,应将这些代码删除。
如图1所示,该方法包含的步骤如算法1所示。首先,使用Apktool[21]反编译APK文件,得到classes.dex文件和AndroidManifest.xml文件。 AndroidManifest.xml文件用于提取权限特征。 JADX工具用于反编译classes.dex文件,获取Java源代码。然后,该方法使用LibRadar [22]工具来检测源代码中存在的第三方库并将其删除。对剩余的Java源代码进行词法分析,得到分词结果,用于训练主题模型。通过主题模型提取每个样本的主题向量。最后,该方法结合主题向量和权限特征来训练分类模型。
3.2 预处理
首先使用Apktool工具反编译APK文件,得到AndroidManifest.xml文件。 xml 文件和classes.dex 文件。然后通过JADX工具反编译classes.dex文件,得到Java源代码。
我们选择Java源代码而不是Smali代码,因为在表达相同的语义时,Smali代码比Java代码长得多。图2(a)显示了Android应用程序源代码中的Java语句,图2(b)显示了实现相同功能的smali代码。对比两张图,可以发现Java代码比Smali代码包含更多的语义信息。
获取Java源码后,需要去除第三方库的代码。在Android应用程序的开发过程中,开发者调用了大量的第三方库来实现广告插件嵌入等扩展的功能。在后续处理之前应过滤这些代码。
现有的Android第三方库检测方法可以分为两类。一是建立第三方库的白名单,提取白名单中库的人为设计的特征。 LibScout[23]就是这样的研究。另一种是基于大量的Android应用样本提取静态特征,利用聚类的方法挖掘潜在的第三方库。 LibRadar [22] 就是此类研究。比较这两种方法,第一种方法的精度受限于白名单的大小。而第二种是基于大数据的,因此更通用,更适合大规模场景。因此,我们选择LibRadar工具来检测并删除第三方库。
Java词法分析器用于对源代码进行分段。分词结果包含标识符、关键字、数字、字符串、分隔符、运算符、位运算符、逻辑运算。由于分词结果中的词数可能过多,超出存储和计算能力的范围,我们采用以下两种措施来平衡词数和计算能力之间的矛盾。
(1)只保留分词结果中的标识符、字符串和数字。这些保留词比其他类型具有更多的语义,并且更有可能包含有效的语义信息。
(2)如果过滤后的词数仍超过40,000个,则通过随机抽样保留40,000个词。对于每个Android应用程序样本,最多获取40,000个单词,这些单词将被视为一个文档。
3.3 模型
在我们的模型中,我们使用词频-逆文档频率(TF-IDF)[24] 来计算每个apk样本的主题向量。
在文档中,术语频率(TF)是指给定单词在文件中出现的频率。对于文档
d
j
d_j
dj中的单词
t
i
t_i
ti,
t
i
t_i
ti的TF表示如下:
t f i , j = n i , j ∑ k n k , j tf_{i,j}=\frac{n_{i,j}}{\sum_kn_{k,j}} tfi,j=∑knk,jni,j
n i , j n_{i,j} ni,j表示 d j d_j dj中 t i t_i ti的个数,k表示字典中单词的个数,分母表示 d j d_j dj中所有单词出现次数的总和。
逆文档频率 (IDF) 是衡量单词普遍重要性的指标。对于单词 t i t_i ti, t i t_i ti的IDF表示如下:
i d f i = log ∣ D ∣ 1 + ∣ { j : t i ∈ d i } ∣ idf_i=\log\frac{|D|}{1+|\{j:t_i\in d_i\}|} idfi=log1+∣{j:ti∈di}∣∣D∣
其中
∣
D
∣
|D|
∣D∣ 表示文档总数,
∣
{
j
:
t
i
∈
d
i
}
∣
|\{j:t_i\in d_i\}|
∣{j:ti∈di}∣ 表示包含单词
t
i
(
n
i
,
j
≠
0
)
t_i(n_{i,j}\neq0)
ti(ni,j=0) 的文档数。
单词
t
i
t_i
ti的TF-IDF表示如下:
t f i d f i , j = t f i , j × i d f i tfidf_{i,j}=tf_{i,j}\times idf_i tfidfi,j=tfi,j×idfi
因此,当某个词在特定文档中出现频率较高而在整个样本集中出现频率较低时,该词的TF-IDF权重较高,TF-IDF往往会突出特定文档中的重要词。记录并削弱常用词的影响。
然后,我们的方法会迭代 Android 应用程序示例的分段结果,以记录所有单词并计算它们在所有文档中的出现次数。我们通过选取出现次数最多的前 100,000 个单词来构建字典。基于建立的字典,使用TF-IDF模型计算每个文档的TF-IDF向量。
在获得每个文档的TF-IDF向量后,通过潜在语义索引(LSI)[25]模型进一步获得每个文档的主题向量。
LSI 模型基于奇异值分解 (SVD)。 SVD可以简单描述为,一个 m × n m \times n m×n 矩阵 A 可以分解为以下三个矩阵:
A m × n = U m × m Σ m × n V n × n T A_{m\times n}=U_{m\times m}\Sigma_{m\times n}V_{n\times n}^T Am×n=Um×mΣm×nVn×nT
其中,矩阵 U U U表示文档与主题之间的相关性,矩阵 ∑ \sum ∑ 表示主题与词汇含义之间的相关性,矩阵 V V V表示单词与词汇含义之间的相关性。
为了将矩阵的维度减少到 k k k,方程: (4) 可以近似为:
A m × n ≈ U m × k Σ k × k V k × n T A_{m\times n}\approx U_{m\times k}\Sigma_{k\times k}V_{k\times n}^T Am×n≈Um×kΣk×kVk×nT
其中 k<m。在LSI模型中,SVD的分解可以描述为以下过程。
- 对于输入的 m 个文档,构造一个包含 n 个单词的字典,并计算每个文档的 TF-IDF 向量。
-
-
A
i
j
A_{ij}
Aij 对应于字典第 i 个文档中第 j 个单词的 TF-IDF。
k
k
k 是语料库中存在的假设主题数。
对于分解的结果, U i , l U_{i,l} Ui,l表示第 i i i个文档与第 l l l个主题之间的相关性, ∑ l , o \sum _{l,o} ∑l,o表示第 l l l个主题与第 o o o个词汇意义之间的相关性,而 V j , o V_{j,o} Vj,o表示第 j j j个单词与第 o o o个词汇意义之间的相关性。
-
A
i
j
A_{ij}
Aij 对应于字典第 i 个文档中第 j 个单词的 TF-IDF。
k
k
k 是语料库中存在的假设主题数。
主题向量的提取仅基于反编译后的源代码。我们也分析了 APK 文件的其他组件。我们认为权限信息对于安卓恶意软件检测非常重要,因此参考 StormDroid [26] 给出的风险权限列表,并从 AndroidManifest.xml 中提取 59 维权限特征。权限特征的每一维代表一个风险权限的存在与否。主题向量和权限特征连接在一起,形成每个样本的最终特征。
我们选择XGBoost[27]模型和SVM[28]模型作为分类器来完成Android恶意软件的检测任务。
4 实验
4.1 数据集
- 德雷宾[13]。 Drebin 数据集包含来自 179 个不同恶意软件家族的 5,560 个 Android 恶意软件样本。样本采集时间为2010年8月至2012年10月。
- AMD[14]。 AMD(Android Malware Dataset)包含2010年至2016年间收集的24,553个Android恶意软件样本,属于71个不同恶意软件家族的135个品种。本文随机提取了10,000个样本进行实验。
- 3.Myblack。 Myblack 数据集由我们收集,包含 5005 个 Android 恶意软件样本。
- AndroZoo[29]。良性数据集是从 AndroZoo 平台下载的,并被 VirusTotal [30] 检测为良性样本。该数据集包含 9561 个良性样本。
4.2 实验设置
比较方法
本文选择基于特征工程的Drebin[13]方法和基于控制流图的CSBD[31]方法。 Drebin 进行了广泛的静态分析,收集了应用程序的尽可能多的功能。这些特征嵌入在联合向量空间中,可以自动识别并用于解释决策。 CSBD 设计了几种机器学习分类器,这些分类器依赖于从应用程序的控制流图构建的一组功能。这两种方法是最先进的基于静态分析的方法。由于这两种方法公开了完整的代码,因此经常被其他研究进行比较。结合我们的方法中的不同特征和模型以及比较方法,实验总共包括六种方法:LSI + XGBoost(我们的)、LSI + SVM(我们的)、LSI + Permission + XGBoost(我们的)、LSI + Permission + SVM(我们的)、Drebin 和 CSBD。
使用良性数据集和三个恶意软件数据集构建三个实验数据集:AMD+AndroZoo、Drebin+AndroZoo 和 MyBlack+AndroZoo。三个数据集的大小分别为19561、15121和14566。
指标
本文通过Fscore、假阴性(FN)率和假阳性(FP)率三个指标来分析实验结果。
F-score综合考虑了分类结果的准确率和召回率,表达如下:
F − s c o r e = 2 × P × R P + R F-score=\frac{2\times P\times R}{P+R} F−score=P+R2×P×R
其中P代表准确率,R代表召回率。 P 和 R 计算如下:
P = P P + N N P P + P N + N N + N P , R = P P P P + P N P=\frac{PP+NN}{PP+PN+NN+NP},R=\frac{PP}{PP+PN} P=PP+PN+NN+NPPP+NN,R=PP+PNPP
其中 PP 表示被正确分类为恶意的恶意软件样本数,PN 表示被错误分类为良性的恶意软件样本数,NN 表示被正确分类为良性的良性样本数,NP 表示良性样本数被正确分类为恶意的样本。
假阴性(FN)率和假阳性(FP)率也是恶意软件检测任务中的重要指标。 FN率代表正样本被错误分类为负样本的比例。 FP率代表负样本被错误分类为正样本的比例。它们的计算方法如下:
F N = P N P P + P N , F P = N P N N + N P FN=\frac{PN}{PP+PN},FP=\frac{NP}{NN+NP} FN=PP+PNPN,FP=NN+NPNP
式中,其他符号的含义与式(7)中相同。
4.3 结果
本节将比较和讨论六种方法在三个数据集上的性能。由于F-score综合了准确率和召回率,因此不单独讨论准确率和召回率这两个指标。
表 1 展示了六种方法在三个数据集上的 F 值,其中加粗数字为最佳结果,蓝色数字为次佳结果。首先,我们比较本文提出的四种方法。对于分类模型,XGBoost 和 SVM 的性能同样出色。XGBoost 在 AMD 数据集和 Myblack 数据集上表现更好,而 SVM 在 Drebin 数据集上表现更好。在特征方面,从 Java 源代码中提取的 LSI 主题向量的分类效果通过添加从 AndroidManifest.xml 文件中提取的权限特征得到了显著提升。
此外,我们将我们的方法的 F 值与两种基线方法进行了比较。在 Drebin 和 MyBlack 这两个数据集上,我们的方法获得了最佳和次佳的 F 值。在 AMD 数据集上,Drebin 方法取得了最佳的 F 值,但我们的方法取得的次佳 F 值仅比最佳值低 0.24。
表 2 和表 3 分别展示了六种方法在三个数据集上的假阴性(False Negative,FN)率和假阳性(False Positive,FP)率。在假阴性方面,Drebin 方法在 Drebin 数据集和 AMD 数据集上表现最佳,而我们的方法在 Myblack 数据集上表现最佳。对于假阳性,我们的方法在三个数据集上表现最佳。Drebin 方法在假阳性率较低时带来了较高的假阴性率,而我们的方法在这两个率上都表现相对较好。
考虑到在三个数据集上的实验结果,我们的方法在两个数据集上获得了最佳的 F 值。在另一个数据集上,我们的方法的性能接近最佳。同时,我们的方法在假阴性率和假阳性率方面表现更好。基于整体结果,可以验证所提出方法的有效性。
5 结论
在本文中,我们提出了一种用于恶意安卓应用程序检测的新特征提取方法,该方法将文本分析领域的主题模型技术引入到安卓应用程序反编译后的源代码中,以挖掘潜在的语义信息。我们使用提取的主题向量和来自 AndroidManifest.xml 的权限信息作为特征,来训练用于安卓恶意软件分类的机器学习模型。我们在三个数据集上将该方法与两种基于特征工程的最先进方法进行比较,我们的方法获得了最佳的整体结果,这表明了所提出方法的有效性。
我们将从以下两个方面继续开展工作。一方面,LSI 模型的可解释性不够。因此,可以考虑其他主题模型来提高主题向量的可解释性。另一方面,该方法没有考虑源代码中的代码混淆问题。代码混淆问题可以在未来得到解决。
笔记提炼
2019年的文章
把反编译出的java代码视为文档,使用主题模型挖掘代码中的潜在主题信息,生成主题向量作为特征在训练机器学习模型
Topic_Model_AMD 方法总结
- 使用apktool提取出dex和xml文件
- 从xml文件提取权限特征
- jadx反编译dex文件获取java源码
- 使用LibRadar检测并记录代码中的第三方库
- 删除第三方库用于主题向量构建
- 对剩余代码使用Java词法分析器进行词法分析
- 对源代码分段
- 记录所有单词出现的次数,构建单词字典
- 主题模型(创新点)
- 根据字典用TF-IDF模型提取TF-IDF向量(重要词语向量)
- 潜在语义索引LSI对TF-IDF向量进一步提取主题向量(LSI特征向量)
- 使用XGBoost模型和SVM模型作为分类器来检测(创新点)
- 特征向量:主题向量、权限特征向量