问题描述
Android 市场的开放性导致了恶意软件(Malware)的盛行。据 360 安全中心报告,每天都能截获数万个 Android 恶意软件,使得 Android Malware Detection 成为研究人员热议的话题。传统的 Android 恶意软件检测方法主要依赖于基于规则或签名的检测机制,其中使用 yara 实现相对简单。但这种基于签名的检测方法是信息密集型的,需要持续收集新的签名,而基于规则的实现则极为复杂,极易导致误报或让狡猾的恶意软件逃过检测。
随着机器学习的流行,越来越多的研究人员开始尝试利用机器学习来实现恶意软件的检测。核心思路是从 Android 的 APK 文件中提取信息,用于训练模型,随后预测其他 APK 文件是否为恶意软件。根据信息提取方法的不同,主要分为两类:一类是通过静态分析,从 APK 中提取 permissions、intents、receivers 等组件,以及通过反编译提取代码调用,利用这些信息进行模型训练;另一类是通过实际安装运行 APK,拦截网络请求和监听系统 API 调用来获取数据,作为模型训练的基础。
在探讨此问题时,由于“Incinerator”项目的动态检测功能尚未完全实现,我们暂时缺乏研究动态分析的条件,因此选择采用静态分析方法进行研究。
当前主流方案
基于静态分析的机器学习训练方案主要包括以下几类:
权限提取训练:
从 AndroidManifest.xml 中提取 permissions 信息进行模型训练。
综合信息提取训练:
从 AndroidManifest.xml 中提取 permissions、intents、receivers 等信息,并通过反编译从 APK 中基于规则抽取 Android 系统 API 调用等信息进行模型训练。
整体 APK 训练:
将整个 APK 文件作为机器学习训练的输入,包括将 APK 文件的二进制字节流作为输入,或通过反编译抽取 opcode 作为训练输入。
据文献报道,这些方案可实现 90% 以上的准确率。尤其是方案 3,准确率在 92%-93% 之间,而方案 1 和 2 在多数研究中可达到 95% 以上的准确率。
我们试图重现文献中的方案,首先着手基于 permissions 的方案进行验证。
数据源:
恶意软件集合:
a. 来自威胁情报公司 abuse.ch 的 Malware APK 集合 2000 个(简称 MB)
b. VirusShare 2020/2021/2022 的 Malware 集合(简称 VS2020/VS2021/VS2022)
良性软件集合:
a. 从应用宝下载的 APK 10000 个
b. 从 APKPURE 下载的 APK 10000 个
训练方法
通过静态分析从 APK 的 AndroidManifest.xml 中抽取 AOSP (Android Open Source Project) permissions,并通过 One-hot Encoding 的方式输入模型进行训练。模型选择采用传统的机器学习二分类模型如随机森林、SVM 等进行训练。经测试,随机森林的效果最佳,准确率可达 98%。
我们选择应用宝的 APK 作为良性样本,VS2022 作为恶意软件样本,进行训练。训练数据如下:
模型 | Precision | Recall | FPR |
随机森林 | 0.983 | 0.983 | 0.056 |
SVM | 0.981 | 0.977 | 0.063 |
然后我们对其他数据集进行测试验证:
数据集 | Precision | Recall | FPR |
APKPure | 0.0 | NAN | 0.59 |
MB | 1.0 | 0.95 | NAN |
VS2020 | 1.0 | 0.96 | NAN |
VS2021 | 1.0 | 0.94 | NAN |
在进行 APKPure 数据集的验证时,发现模型的假阳性率异常高,超过了 50%,这表明模型在不同数据集的交叉验证上表现不佳。同时,在 MB、VS2020、VS2021 数据集上得到的高准确率由于高假阳性率而变得无意义。
为了深入理解模型的预测表现,我们选择使用 LinearSVM(线性支持向量机)来解释模型的预测结果,并尝试探讨可能出现的问题:
在训练过程中,共有 265 个权限被用于训练模型。我们重点分析了对于 Malware 预测结果影响最大的 30 个权限:
导致 Benign 结果最重要的 30 个权限:
在表格中,第二列显示了通过 SVM 计算得到的权重值。由于在标签设定中,Malware 被标记为 1,而 Benign 被标记为 0,且训练数据的格式是 0,1,1,0,...0,1,1,0,...这样的布尔值,因此,当权重为正时,该权重在计算 Malware 的预测结果时具有较高的重要性;权重值越大,其重要性越高。相反,当权重为负时,该权重在计算 Benign 的预测结果时具有较高的重要性;权重值越小,其重要性越高。
通过分析这些权限及其功能,我们发现 Malware 相关的权限通常比 Benign 相关的权限具有更高的危害性。在一定程度上,这种模型的设计是合理的。例如,模型成功识别了与 SMS 相关的权限主要与 Malware 相关,并赋予了较高的权重,这意味着,基本上,一个 APP 如果包含 SMS 权限,就非常可疑。实际上,普通的 APP 不应该请求此类权限,因为短信管理通常是系统 APP 的职责。
然而,这里存在一个问题:权限的存在是因为 Android 系统认为某些行为可能不妥,需要用户确认。所以,理论上,所有需要请求的权限都有可能对用户造成损害。因此,没有请求权限应该被视为一个加分项。但在二分类机器学习的情境下,模型会做出区分,因为 Benign 类别的存在意味着一定会有一部分权限被视为支持 Benign 的证据。
现在我们来分析为什么会出现如此高的假阳性率: 我们使用 LinearSVC 来解释模型的预测结果,并对一些具有假阳性的权限信息进行分析:
而真阳的权限信息:
通过分析,我们发现了一个模式:拥有较少权限的 APK 往往会被误判,而权限较多的 APK 基本能得到正确的预测。深入探究后,我们理解到这种现象的出现主要是由于 APKPure 样本中大多数 APK 的权限数量较少,而我们的训练模型主要基于权限较多的应用宝 APK 样本。因此,预测误差的产生在一定程度上是由样本差异导致的。
为了解决这个问题,一个直接的方法是将 APKPure 的数据也纳入训练过程,以增强模型的泛化能力和预测准确性。
我们采取了以下措施:从 APKPure 样本中随机抽取一半,即 5000 个 APK,同时从应用宝样本中随机抽取一半,约 5000 个 APK,一同用于模型的训练。然后,我们使用这个新训练得到的模型来预测未参与训练的样本。结果显示,新模型的预测准确率得到了显著提高。
模型 | Precision | Recall | FPR |
随机森林 | 0.994 | 0.967 | 0.008 |
SVM | 0.994 | 0.967 | 0.008 |
然后我们对其他数据集进行测试验证:
数据集 | Precision | Recall | FPR |
APKPure 未参与训练的样本 | 0.0 | NAN | 0.018 |
MB | 1.0 | 0.878 | NAN |
VS2020 | 1.0 | 0.92 | NAN |
VS2021 | 1.0 | 0.89 | NAN |
假阳性率已降至可接受的水平。这个实验揭示了一个重要的现象:在训练集上获得理想的结果相对容易,但在现实世界中准确预测却可能面临挑战。无人能保证所收集的样本完美地反映了现实世界的情况,而我们的目标是识别那些真正与恶意软件(Malware)相关的特征。因此,我们决定尝试探索其他可能的解决方案。
1. 基于 Intents 和 Receivers 的训练
随后,我们扩展了特征集,加入了从 AndroidManifest.xml 中提取的 intents 和 receivers 信息进行训练,然而,这并没有提高模型的准确率。
2. 基于系统 API 调用的训练
我们进一步尝试提取 APK 中的所有系统 API 调用,将其转换为适合卷积神经网络(CNN)的格式,并通过 CNN 来训练模型。在训练集上,模型达到了令人满意的 97% 的准确率,但在数据集交叉验证时,表现仍然不尽如人意。
在这过程中,我们遇到了几个问题:、
API 调用频率的不明显差异: 最初,我们通过反编译提取了所有出现过的 API 调用,却发现这些 API 的调用频率并没有明显差异。例如,我们原本认为 accessibilityservice 的调用明显与恶意软件相关,却发现在良性软件中也频繁出现。后来我们了解到,这主要是因为大多数 APK 都依赖于 android 这个库,而该库中包含了大量的系统 API 调用。由于 Malware 和 Benign APK 都依赖于大量的第三方库,这些库中存在大量的系统 API 调用,使得我们难以从系统 API 调用的统计结果中区分 Malware 和 Benign。即便我们使用了 incinerator 的 SCA 分析功能来检测和剔除这些第三方库,结果仍然不尽如人意。
第三方库的干扰: 我们发现,很少有研究考虑到第三方库的干扰,并提出剔除第三方库的具体方案。如果不剔除这些库,基于静态分析的方法几乎毫无意义,因为静态抽取会抽取出大量未被调用的 API,而这在 Malware 和 Benign APK 中没有明显区别。
反编译和脱壳问题: 由于这种方法涉及从 APK 中抽取系统 API 调用,需要进行反编译。然而,许多 Malware 都加壳处理,而脱壳是一个复杂的对抗技术。我们查阅的资料中,很少提到这一点。脱壳对于非专业团队来说可能太过困难,但至少应该从数据集中筛选出没有壳的 APK。如果不进行脱壳,直接抽取的话,只能得到极少数的 dexloader 等系统 API 调用,这大大影响了训练效果。
3. 回归基于 Permissions 的模型
鉴于前述的尝试未能取得预期效果,我们重新回到基于 Permissions 的模型,寻求通过其他方法提升交叉验证的准确率。我们进行了以下尝试:
通过 Select 模型选择 Permissions 采用此法的目的是寻找 Malware 实际所利用的 Permissions。然而,实际测试结果显示,训练准确率下降,验证准确率也下降,且交叉验证的准确率更是降低。
我们的实验过程如下: 使用 SelectFromModel 方法,基于 RandomForestClassifier 模型(该模型包含所有参与训练的数据)进行参数抽取。我们分别抽取了 100、50、30 个 Permissions 进行实验,并得到了如下数据:
选取 100 个 Permissions训练数据:
模型 | Precision | Recall | FPR |
随机森林 | 0.989 | 0.974 | 0.013 |
数据集 | Precision | Recall | FPR |
APKPure | 0.0 | NAN | 0.64 |
MB | 1.0 | 0.95 | NAN |
VS2020 | 1.0 | 0.96 | NAN |
VS2021 | 1.0 | 0.94 | NAN |
选取 50 个 Permissions训练数据
模型 | Precision | Recall | FPR |
随机森林 | 0.981 | 0.986 | 0.063 |
数据集 | Precision | Recall | FPR |
APKPure | 0.0 | NAN | 0.59 |
MB | 1.0 | 0.94 | NAN |
VS2020 | 1.0 | 0.96 | NAN |
VS2021 | 1.0 | 0.94 | NAN |
训练 30 个 Permissions训练数据
模型 | Precision | Recall | FPR |
随机森林 | 0.983 | 0.983 | 0.054 |
数据集 | Precision | Recall | FPR |
APKPure | 0.0 | NAN | 0.59 |
MB | 1.0 | 0.96 | NAN |
VS2020 | 1.0 | 0.96 | NAN |
VS2021 | 1.0 | 0.95 | NAN |
分析及新的尝试
从前述数据中可见,减少 Permissions 的数量并未能改善假阳性率或提高准确率。
利用自编码器(Auto Encoder)进行降维
为了进一步尝试改善模型表现,我们转向了自编码器(Auto Encoder)技术,期望通过对 Permissions 的分组和降维来提高准确率。自编码器是一种能够学习数据编码的神经网络,通常被用于降维或特征学习。我们的想法是通过自编码器将 Permissions 的高维数据转换为低维数据,同时保留与 Malware 识别相关的重要信息。
然而,尽管我们尝试了自编码器的降维方法,交叉验证的结果仍然不尽如人意,假阳性率依然较高。
模型 | Precision | Recall | FPR |
随机森林 | 0.977 | 0.980 | 0.074 |
数据集 | Precision | Recall | FPR |
APKPure | 0.0 | NAN | 0.64 |
MB | 1.0 | 0.95 | NAN |
VS2020 | 1.0 | 0.95 | NAN |
VS2021 | 1.0 | 0.92 | NAN |
通过业务逻辑选择 Permissions
随后,我们尝试通过业务规则来挑选适当的 Permissions。我们的方法是这样的:
我们统计了所有 Malware 中每个 Permission 的出现频率 mp 和所有 Benign 中每个 Permission 的出现频率 bp。
然后计算了 bp/mp
然而,这种方法也未能提高训练准确率和验证准确率。例如,android.permission.INTERNET 这样的权限在 Malware 和 Benign 中出现的概率非常接近,大约都在 97% 左右,这样的权限参与训练并没有太大的意义。类似地,android.permission.WAKE_LOCK 在 Malware 和 Benign 中出现的概率也非常接近,大约在 80% 左右。
我们还尝试了其他研究论文中提到的一些方法。经过测试,我们发现无论采取何种方法来筛选 Permissions,筛选后的训练准确率都不如不筛选、直接使用所有 Permissions 进行训练的准确率高。这个发现与许多将 Permissions 筛选作为主要研究目的的论文的结论相左。
结论
经过多次尝试,我们暂时未能训练出一个在单一数据集上训练,而在其他数据集上也具有理想准确率的模型。因此,我们决定将应用宝和 APKPure 的数据合并作为 Benign APK 的训练集,同时将其他几个 Malware 数据集也合并作为 Malware APK 的训练集,以提高样本的平均均衡度。
当然,我们也发现了一些可能的优化方向:
我们注意到 Malware 和 Benign 的 APK 签名存在一定的模式,如果能够验证这些模式,可以将其纳入现有模型中。
在手动分析样本时,我们发现许多 Malware APK 样本在静态分析阶段无法判断为恶意,因为它们的权限没有任何可疑信息。例如,许多 dropper、downloader 等类型的恶意 APK,在权限上与 Benign APK 没有明显区别。因此,人工筛选恶意 APK 可能有助于提高训练准确率。
同时,将动态检测的信息纳入训练模型也是一个值得尝试的方向。我们计划在后续的研究中加入动态信息以提升模型的表现。
原文链接:https://www.liansecurity.com/#/main/news/TfrG0IoBQKl-d7iA6Wuh/detail
还没有评论,来说两句吧...