admin管理员组

文章数量:1567020

Experiences of Landing Machine Learning onto Market-Scale Mobile Malware Detection(ccs 顶会)(没看完)

摘要

        应用市场是当今移动生态系统的关键所在,也是恶意软件的天然传播渠道,因为它们实际上为恶意应用 "提供了可信度"。在过去的十年中,人们一直在探索机器学习(ML)技术,以实现自动、稳健的恶意软件检测。遗憾的是,迄今为止,我们尚未看到基于 ML 的恶意软件检测解决方案在市场上大规模部署。为了更好地了解现实世界中的挑战,我们与一个主要的安卓应用市场(T-Market)开展了一项合作研究,该市场为我们提供了大规模的地面实况数据。我们的研究表明,成功开发此类系统的关键是多方面的,包括特征选择/工程设计、应用分析速度、开发人员参与和模型演化。上述任何一个方面的失败都会导致整个系统的 "木桶效应"。我们将讨论在构建这样一个由人工智能驱动的恶意软件检测系统时,我们所做的精心设计选择以及第一手部署经验。我们实施了我们的设计,并在 T-Market 中对其有效性进行了一年多的检验,使用单个商品服务器每天检测 ∼ 10K 个应用程序。评估结果表明,该设计的总体精确度为 98%,召回率为 96%,每个应用程序的平均扫描时间为 1.3 分钟。

CCS 概念:- 安全与隐私→移动平台安全;恶意软件及其缓解。

1 引言

        Google Play 和亚马逊 AppStore 等应用程序市场在当今的移动生态系统中发挥着重要作用,大多数移动应用程序都是通过这些市场发布、更新和分发给用户的。另一方面,这些市场也成为传播恶意软件的便捷渠道。更糟糕的是,大多数攻击者更喜欢使用这一渠道,因为当一个应用程序在知名的应用程序市场发布时,就会 "赋予 "该应用程序 "可信度"。此外,移动设备通常会进行预配置,默认情况下只允许从应用市场安装应用程序[50]。因此,目前所有主要的商业应用市场都需要市场规模的自动恶意软件检测[18]。

        在过去十年中,机器学习(ML)技术被广泛用于恶意软件检测,因为它们不依赖于特定的规则,因此被认为更加自动化和稳健。文献中存在大量基于 ML 的技术,从简单的基于指纹的反病毒检查 [50]、静态代码检查 [7] 到复杂的动态行为分析 [42]。遗憾的是,我们尚未看到任何关于这些解决方案在市场规模应用时的有效性的报告。

        在本文中,我们将介绍构建和部署人工智能解决方案的经验。通过与一个主要的安卓应用市场(即腾讯应用市场1 1https://sj.qq/myapp/ 或简称天猫市场)合作,我们获得了应用(包括已发布和被拒绝的应用)及其相应标签的大规模地面实况数据。通过全面分析数据和现有的基于 ML 的恶意软件检测解决方案,我们发现关键挑战在于多个方面特征选择、特征工程、应用程序分析速度、开发人员参与以及 ML 模型随时间的演变。

        更重要的是,我们注意到上述任何一个方面的失败都会导致 "木桶效应"[40](从而徒劳无功)。例如,特征选择不仅会影响检测精度,还会影响分析应用程序所需的时间(这两方面对市场规模的解决方案都有严格要求)。此外,特征工程决定了检测的鲁棒性和模型演化的难度。此外,检测精度和速度都会影响开发人员提交应用程序的参与度,而这对商业应用程序市场的繁荣至关重要。

        为了在市场范围内构建理想的 ML 驱动的恶意软件检测系统,我们选择了轻量级和可扩展的特征提取设计:以应用程序接口为中心的动态分析,可在应用程序运行时监控安卓应用程序接口的调用,从而实现高速分析。鉴于 Android SDK 应用程序接口几乎提供了典型应用程序的所有功能,因此在以往几乎所有的研究中,它们仍然是事实上的特征选择[2, 31, 33, 39]。事实上,我们的研究表明,在许多情况下,使用更复杂的特征并不能明显提高检测准确率[1, 42, 46]。

        接下来,我们注意到当前的 Android SDK 提供了超过 50,000 个应用程序接口(API),因此在具体选择(应用程序接口)功能时采用了一种原则性的、数据驱动的方法。理由有三点。首先,所选 API 的数量对动态分析时间有不可忽略的影响(最多相差 50 倍)。其次,与监控所有 50,000 个应用程序接口相比,战略性地监控较少数量的应用程序接口可获得更高的检测精度,这可能是由于过度拟合的可能性降低了。第三,从不同来源识别出的 API 可以相互补充;明智地将它们结合起来有助于大大提高检测准确率。基于上述考虑,我们选择了总共 426 个关键 API 作为 ML 特征,并采用了轻量级随机森林 ML 算法(在多种 ML 算法中),该算法在 T-Market 大规模数据集中提供了最佳检测准确率(96.8% 的精确率和 93.7% 的召回率)

        为了进一步提高检测精度,我们从对手的角度来识别隐藏的特征。纯粹依赖 Android API 进行恶意软件检测的局限性在于,为了实现某些 API 的功能,攻击者可以绕过 API 调用,使用 Java 反射和意图(Android 的 IPC 机制)等其他机制。从我们的数据集中,我们观察到恶意应用程序使用了这两种机制来隐藏它们的某些功能。为了说明这一点,我们还在动态分析中捕获了请求的权限和使用的意图。捕捉到的 "间接 "特征与 API 调用特征相结合,就能更全面地了解应用程序的运行行为。应用这一增强功能后,我们数据集的检测精度和召回率进一步提高到 98.6% 和 96.7%。

        在获得所需的功能后,我们将重点转向提高应用程序分析的运行性能。我们构建了应用程序仿真系统,以便在功能强大的 x86 服务器上高效运行(第 5.1 节)。为了提高运行时性能,我们运行了安卓操作系统的原生 x86 端口[21],并将应用程序的原生代码从 ARM 转换为 x86(使用英特尔开发的最先进的动态二进制转换框架[22])。与基于 ARM 的安卓操作系统和应用程序的全系统二进制转换(使用基于谷歌 QEMU 的安卓模拟器)相比,我们可以将应用程序的执行时间缩短 70%。通过应用程序崩溃检测和模拟器回退,系统还变得更加可靠。

        对于基于 ML 的系统来说,假阳性和假阴性通常是不可避免的。在 APICHECKER 中,假阳性应用程序(由开发人员投诉)和假阴性应用程序(由最终用户报告)都要进行人工分析,但方式各不相同。我们选择主动避免前者(日常),因为这大大增加了人工干预处理开发者投诉的负担。通常情况下,被标记的恶意应用程序中有 90% 是更新过的应用程序,可以根据其以前的版本进行快速审核,因此完全需要人工检查实际上是可以承受的。相比之下,我们很难避免后者,因此只能根据用户报告进行人工分析。幸运的是,我们观察到,少量假阴性应用程序的存在实际上对 T-Market 的正常运行影响不大。人工检测结果显示,87%的假阴性应用程序几乎没有使用我们选择监控的关键应用程序接口,因此功能相当简单,不会对最终用户构成严重的安全威胁。

        我们将上述所有努力体现在一个名为 APICHECKER 的实际系统中,该系统已于 2018 年 3 月在天猫超市投入使用。它运行在单个商品服务器上,每天可以审核 ∼ 10K 个新提交的应用程序。APICHECKER 扫描一个提交的应用程序平均需要 1.3 分钟,这对于开发者来说是可以接受的(考虑到 Google Play 中每个应用程序的扫描时间通常为 5 分钟[26])。由于我们每月都会根据新应用和新的 Android SDK API(如有)自动更新 ML 模型(第 5.3 节),因此自首次部署以来,总体精确度和召回率一直高于 98% 和 96%。随着模型的发展,所选关键 API 的数量仅在 425 和 432 之间小幅波动。

        总之,本研究展示了我们为实施、部署和运行市场规模的移动恶意软件检测系统而做出的几项关键设计决策。据我们所知,这是首次进行如此大规模的研究。从高层次来看,我们的经验表明,尽管机器学习是移动安全的强大基石,但在战略性应用时应考虑到准确性、性能、通用性、长期稳健性和可部署性等多个方面。例如,基于这些考虑,我们做出了一个明智的决定,即 APICHECKER 不使用深度学习,而是使用随机森林,它可以达到相当的分类准确性,同时还具有训练时间短、操作轻便和可解释性强等优点。我们还展示了一种系统化的特征构建方法,在自动安全分析中,这一过程可能比 ML 模型选择本身更为重要。

        数据集和工具发布。我们选定的 426 个关键框架 API 列表可在 https://apichecker.github.io/ 上查阅。一旦获得 T-Market 的批准,我们还将向研究界发布我们的分析日志以及我们实施的高效模拟器。

        伦理考虑。本研究中的所有分析任务均遵守 T-Market 与在 T-Market 发布应用程序的开发者之间达成的协议。为了保护开发者的隐私,在提及作为示例或案例研究的个别应用程序时,我们会匿名。

2 背景与动机

        在本节中,我们首先介绍安卓应用程序开发的基础知识,以便更好地理解移动恶意软件检测。然后,我们介绍 T-Market 和其他应用市场采用的恶意软件防御机制,以及相关的挑战。

安卓应用程序开发基础知识。安卓是基于 Linux 内核和 ARM 架构的开源操作系统。安卓应用程序通常用 Java 编写,编译成 Dex(Dalvik Executable)字节码,然后压缩并部署为一个安卓包(APK)存档。具体来说,APK 文件包含配置文件、编译代码和其他一些文件。其中,配置文件 AndroidManifest.xml 保存了元数据(如软件包名称、请求的权限、Android 组件声明和依赖关系),编译代码 classes.dex 包含了 API 使用信息。应用程序在自己的 Dalvik 或 ART(Android Runtime)虚拟机实例中运行,虚拟机实例作为 Linux 进程运行,具有唯一的 UNIX 用户 ID 和一些与权限相对应的组 ID,因此应用程序对系统资源的访问受到严格限制。应用程序必须在 Android 配置文件(AndroidManifest.xml)中申请敏感用户数据和某些系统功能的权限。Android 中的这种安全模型确保每个应用程序都在沙箱中运行。

        在开发 Android 应用程序时,Android 框架(包含 Android 操作系统的全部功能集)提供了丰富的 API,使应用程序能够与其他应用程序和系统进行交互。为了确保应用程序的完整性,应用程序需要在其配置文件中申请敏感用户数据和某些系统功能的权限。只有当系统(有时甚至是用户)授予这些权限后,才能执行相应的代码(和应用程序接口)。此外,Android 中的进程间通信(IPC)是通过一种名为 Binder 的机制实现的,它用于执行从一个 Java 进程到另一个 Java 进程的远程过程调用(RPC);这种机制还能使框架 API 与 Android 系统服务进行交互。开发人员只需传递一个类似于消息的对象(如 Intent),即可通过某些 API 实现 IPC。通过上述机制,Android 系统的大部分功能都暴露给了开发者。另一方面,虽然应用程序在沙盒中运行,但丰富的 API 已被攻击者利用开发恶意应用程序,对 Android 生态系统构成持续威胁。

        当前市场层面的防御机制和挑战。在当今的应用市场上,恶意应用利用各种手段(如重新包装和更新攻击)将自己伪装成良性应用[25],诱导用户从应用市场下载安装,从而进行难以察觉的恶意行为。为应对此类威胁,谷歌于2012年推出了专有的 "Bouncer "系统[26],用于扫描上传到Google Play上的应用程序,使该平台上的恶意应用程序数量减少了40%。然而,由于存在大量没有此类恶意软件检测功能的第三方应用程序市场,恶意应用程序仍然得以传播。

        为了深入而实际地探讨这一问题,我们在本文中与 T-Market 合作。T-Market 是一个第三方应用程序市场,自 2012 年推出以来已发布了 600 多万个应用程序,每天有 2 000 万用户下载 3 000 多万个 APK。为了保护用户,T-Market 每天都会对开发者提交的新应用和更新应用进行审核。

        为了准确判断托管应用程序的恶意程度,TMarket 于 2014 年推出了一套复杂的应用程序审查流程,主要包括:1)基于指纹的防病毒检查;2)专家提供信息的 API 检查;3)用户报告驱动的人工检查。首先,反病毒检查根据赛门铁克、卡巴斯基、诺顿、McAfee 等反病毒服务公司提供的病毒指纹[50]对应用程序进行检查。以及 T-Market 自己收集的病毒指纹。其次,API 检查通过监控应用程序代码中一组选定 API 的调用来识别恶意应用程序。这些 API 是由安全专家根据经验选出的,他们的直觉是这些 API 的某些调用模式(组合和顺序)意味着潜在的安全威胁[1]。第三,经过这两个步骤后,仍会出现假阳性和假阴性。T-Market 目前依靠开发人员报告误报,以及终端用户报告误报。对于这些报告案例,会进行人工检查以确定其恶意性。

        在这个检测过程中,基于指纹的反病毒检查只能检测已知的恶意软件样本。因此,最关键的防御任务--检测零时差恶意软件--主要依赖于 API 检测和人工检测步骤[20]。由于人工检测速度较慢(分析一个应用程序可能需要几天时间),T-Market 对改进 API 检测步骤并实现与 "Bouncer "系统相当的性能非常感兴趣。特别是,它希望了解当今流行的 ML 技术是否能够实现这一目标,因为这些技术不依赖于特定规则(来自安全专家),因此通常被认为更加自动化和强大

3 相关工作

表 1.具有代表性的安卓恶意软件研究,这些研究通过研究一组选定的潜在有用框架 API 来检测恶意应用程序。"- - "表示未知。

        对于安卓应用程序的开发,安卓框架提供了丰富的应用程序接口(API),使应用程序能够与其他应用程序和系统进行交互。本节从收集应用程序 API 使用信息的静态和动态方法两方面,回顾了之前使用 ML 技术的基于 API 的恶意软件检测解决方案。我们还将从不同角度对现有解决方案和我们的工作进行比较。

        静态分析。静态 API 使用信息可直接从应用程序的 APK 中提取。然后,可以应用机器学习或基于规则的方法来确定应用程序的恶意程度。例如,Sharma 等人[35] 从 1600 个应用程序中提取了 35 个与应用程序恶意程度相关的 API,并结合 Naive Bayesian 和 kNN 分类器,实现了 91.2% 的精确度和 97.5% 的召回率,用于恶意软件检测。其他代表性工作包括 DroidAPIMiner [1]、Stowaway [15]、DroidMat [43]、Droid-Sec [49]、RiskRanker [20] 和 DREBIN [6]。

        DroidAPIMiner [1] 根据使用频率提取关键 API,并比较了四种机器学习分类器的性能,其中 kNN 的准确率为 99%,误报率为 2.2%,性能最佳。在分析速度方面,对一个 APK 文件进行分类平均需要 25 秒。Stowaway [15] 是一款自动静态分析工具,它从 964 个应用程序中提取了 1 259 个具有限制权限的 API,并在此基础上构建了一个 "权限地图",用于检测应用程序的过度权限。DroidMat [43]也采用了同样的策略来确定 1738 个应用程序的恶意程度。DroidMat [43] 采用 k-means 算法来增强恶意软件分类模型(kNN)。

        RiskRanker [20] 对 118K 个应用程序进行了两阶风险分析评估(每个应用程序耗时约 41 秒),通过识别某些看似无害的 API 使用规则(这些规则很可能是恶意软件的指标),最终报告了 3281 个风险应用程序。此外,Droid-Sec [49] 提出了一种基于 ML 的方法,利用从 250 个 Android 应用程序的静态分析中提取的 64 个敏感 API 和动态分析中提取的 18 种行为来检测恶意软件。该研究还对深度学习模型和其他五种经典机器学习模型进行了比较,并利用深度信念网络实现了 96.0% 的最高准确率。

        DREBIN [6] 采用混合策略,从 129K 个应用程序中收集大量特征,包括权限受限的 API可疑 API(可能涉及敏感操作)请求的权限网络地址等。然后,它在真实设备上收集特征平均需要 10 秒钟,并利用支持向量机(SVM)分类器识别输入特征的某些模式。DREBIN 不会报告收集到的 API 或检测准确率。

        动态分析。由于动态分析不受代码混淆和动态代码加载的影响,因此可以更深入、更全面地了解应用程序的行为。例如,Yang 等人[46]开发了一个动态应用程序行为检测平台,通过检测 19 个 API 的运行时使用情况,这些 API 在获取设备/系统信息、访问网络和从用户账户收费方面受到三种特殊权限的限制;他们对每个应用程序进行了约 18 分钟的检测,并使用 SVM 模型实现了 92.8% 的精确度和 84.9% 的召回率。文献中存在大量类似的动态分析系统,如 DroidDolphin [44]、IntelliDroid [42]、TaintDroid [14] 和 DroidCat [9]。

        DroidDolphin[44]基于大数据分析和SVM机器学习算法构建了一个动态分析框架,在大约17分钟内检查了一个应用程序的25个API和13种敏感操作的使用情况,并取得了90%的精确度和82%的召回率。IntelliDroid [42]从2,326个应用程序中提取了228个 "目标 "API的特定API调用路径和敏感事件链,这些API可能有助于TaintDroid [14]识别的敏感操作。根据提取的信息,它通过动态分析检测恶意软件,平均每个应用程序只需 138.4 秒。此外,DroidCat [9] 利用 122 个行为特征(包括手动挑选的 API、组件间通信和潜在风险源/汇)和随机森林分类模型,实现了高达 97.5% 的精确度和 97.3% 的召回率。每个应用程序的特征计算和测试平均耗时 354 秒。遗憾的是,它无法处理动态代码加载的情况,因此大大降低了其通用性。

        鉴于动态分析通常需要大量时间,一些研究采用了缩短检测时间的方法,例如只检测 50K API 底层的 370 个 Linux 系统调用,以降低时间成本[38]。这些方法通常都是临时性的,而且往往会因失去 API 对应用程序语义的表达能力而牺牲检测的准确性。

        与我们的工作比较。尽管采用了类似的以应用程序接口为中心的分析方法,但我们的工作在几个方面与现有研究有所不同:首先,我们的测量研究规模(就研究的应用程序数量而言)要大得多。其次,我们对应用程序接口的选择进行了创新,并识别了隐藏特征,从而进一步提高了准确性。第三,我们优化了动态执行(仿真)基础设施,大大缩短了应用程序的分析时间,同时保证了运行时的可靠性。第四,我们成功实现了系统的商业化部署,并及时更新了 ML 模型。总之,我们的工作为市场规模的基于 ML 的恶意软件检测提供了首个实用而全面的解决方案,并报告了商业部署结果。

4 协作研究

        在本节中,我们将采用一种原则性的大数据驱动方法来研究由 ML 驱动的恶意软件检测,并使用一个来自 T-Market 的 ∼500K 应用程序的地面实况数据集(§4.1)。此外,我们还构建了一个以 API 为中心的动态分析引擎(§4.2),在应用程序运行时挂钩 API 调用,并检查不同的分类模型。之后,我们在§4.3中报告了基本研究结果,这些结果为我们的特征选择(§4.4)和特征工程(§4.5)提供了有效指导。

4.1 应用程序数据集

        我们的数据集包含 10 个月内(从 2017 年 3 月到 12 月)提交到 T-Market 的 501 971 个新的和更新的应用程序。请注意,我们的数据集中有 85% 的应用程序是早在 2014 年就提交到 T-Market 的更新版应用程序。此外,包名相同但 MD5 哈希码不同的 APK 被视为不同的应用程序。具体而言,T-Market 通过第 2 节中介绍的相当复杂而有效的应用程序审查流程,为每个应用程序提供恶意标签(恶意或良性)。这些标签是通过至少四种最先进的基于指纹的反病毒检查2(2 具体而言,各杀毒引擎声称的误报率低于 5%。当这些引擎都将某个应用程序标记为恶意程序时,T-Market 会将该应用程序视为恶意程序;否则,T-Market 会对该应用程序进行人工检查。因此,在我们的训练集中,被错误标记的应用程序不应超过(1 - 95%))、经验性 API 检查以及由开发者和用户反馈触发的人工检查获得的。因此,尽管我们的数据集中包含了一小部分虚假标签的应用程序,但总体而言,我们的数据集能够提供可信的、无偏见的基本事实。数据集中总共有 463,273 个良性应用程序和 38,698 个恶意应用程序;恶意应用程序并未向用户发布,而是被隔离在 T-Market 数据库中。

4.2 动态分析引擎

        为了拦截和记录框架 API 的运行时调用,我们基于谷歌的官方 Android 模拟器[5]和 Xposed 挂钩框架[32]构建了一个动态分析引擎,它可以在目标 API 实际调用之前对其进行拦截。同时,我们使用 Monkey UI exerciser [4]探索每个应用程序,它可以在应用程序和系统层面生成 UI 事件流。此外,我们还应用了表 2 所列的九种主流机器学习算法。它们包括 Naive Bayes (NB)、CART 决策树、逻辑回归 (LR)、k-近邻 (kNN)、支持向量机 (SVM)、梯度提升决策树 (GBDT)、人工神经网络 (ANN)、深度神经网络 (DNN) 和随机森林 (RF)。我们之所以选择它们,是因为现有的研究和系统 [1, 6, 9, 35, 43, 44, 46, 49] 已经使用了它们。我们将它们应用到收集到的日志中,以得出一个合适的分类模型来确定应用程序的恶意程度。这里的一个关键设计决定是使用成熟的程序分析(即在应用程序仿真[5]、API 挂钩[37]和用户界面测试[3]方面广受好评的应用程序行为分析工具链)和机器学习技术作为我们的构建模块,因为我们的引擎将是商业系统的一部分,它应该能够容纳应用程序市场托管的所有应用程序。

        应用程序模拟环境。我们将谷歌的安卓模拟器部署在一个由(16 台)商品 x86 服务器(运行 Ubuntu 16.04 LTS 64 位的 HP ProLiant DL-380 服务器)组成的集群上,每台服务器都配备了 5×4 核 Xeon CPU @ 2.50 GHz 和 256-GB DDR 内存。在每台服务器上,我们在 16 个内核上同时运行 16 个模拟器,其余 4 个内核用于任务调度、状态监控和信息记录。然后,使用安卓调试桥接器(adb)工具在仿真器上并行运行 50 万个应用程序。具体来说,对于每个应用程序,我们按顺序执行 adb 命令,自动安装应用程序、运行 Monkey UI 练习器、记录运行日志、卸载应用程序并清除残留数据。我们仅使用 Monkey 的执行时间来测量应用程序的整体仿真时间。此外,利用 Xposed,我们不仅可以拦截目标 API 的调用(并记录其名称和参数),还可以实现回调接口以执行附加操作(例如,挂钩某个 Activity,篡改返回值以绕过用户登录或模拟真实设备的行为),从而为仿真提供便利。

        在仿真过程中,我们注意到一些恶意程序试图识别自己是否在仿真器上运行,从而抑制其恶意活动。它们通常会检查安卓系统的静态配置、用户输入的动态时间间隔以及用户设备的传感器数据,以识别模拟器的存在。为防止此类检测,我们从以下四个方面对模拟器进行了改进:

  • 首先,我们更改了模拟器的默认配置,包括它们的身份(IMEI 和 IMSI)、PRODUCT/ MODEL 类型和网络属性(例如在 /proc/net/tcp 中维护的 TCP 信息)。
  • 其次,我们调整了 Monkey 的执行参数 throttle 和 pct-touch,它们分别控制输入间隔和触摸事件在所有输入中所占的百分比,使生成的用户界面事件看起来更逼真。具体来说,节流阀设置为 500 毫秒(人类输入的平均间隔),而 pct-touch 则根据应用类型设置为 50% ∼ 80%,因为触摸事件通常在普通用户的日常输入中占主导地位。
  • 第三,我们在模拟器上重放从一些真实智能手机上收集的传感器数据(如加速度计、陀螺仪),以提高其真实性[19]。
  • 最后,我们对 Xposed 的相关库进行了混淆处理,并更改了非常重要的 PackageManager 类中某些方法(如 getInstalledApplications)的返回值,这样被研究的应用程序就很难检测到 Xposed 的存在。

        为了量化增强型仿真环境的效果,我们构建了一个对照实验,在真实 Android 设备(Google Nexus 6)、原始仿真器和增强型仿真器上运行相同的应用程序样本集。具体来说,我们在这三种环境中运行数据集(50 万个应用程序)的无偏见子集(1%)。我们发现,在原始模拟器上,只有 86.6% 的应用程序调用了与真实 Android 设备上(它们调用的)相同数量的 API,而在我们的增强型模拟器上,多达 98.6% 的应用程序调用了与真实 Android 设备上相同数量的 API。其余的应用程序(1.4%)调用的 API 数量较少,这是因为它们需要从特殊传感器(如麦克风)获取实时数据,而我们的模拟环境目前无法生成这些数据。这表明我们对应用程序仿真环境的改进是有效的。

        用户界面探索方法。我们的动态分析引擎需要实现较高的用户界面覆盖率,以模拟尽可能多的用户活动。最初,我们使用活动覆盖率作为用户界面覆盖率的主要指标[27],因为每个 Android 应用程序都在其配置文件(AndroidManifest.xml)中指定了可能的活动对象。然而,这一指标过于悲观,因为它考虑到了代码实际上并未引用的一些活动。

        因此,为了计算 Android 应用程序实际引用指定活动的比例,我们编写了一个脚本,自动扫描数据集中每个非混淆 APK 的配置文件和代码。扫描结果表明,平均只有 88% 的指定活动被实际引用。此外,我们还定义了一个更精确的指标--引用活动覆盖率(RAC),用于量化用户界面覆盖率RAC 是应用程序仿真过程中检测到的(实际使用的)活动数量与应用程序引用的活动数量之间的比率。

        Xposed [32]可以检测到应用程序仿真过程中实际使用的Activities。从数量上看,我们发现执行 ∼100K 个 Monkey 事件平均可实现近 86% 的 RAC - 执行更多的 Monkey 事件几乎无法提高 RAC。然而,执行 100K 个 Monkey 事件平均需要 2,142 秒(35.7 分钟)。如此长的模拟时间对于应用商店运营商和开发者来说都是难以接受的(考虑到 Google Bouncer 只需要不到 5 分钟的时间来分析每个提交的应用 [26])。为了解决这个问题,我们需要仔细平衡有效性(RAC)和效率(模拟时间)。

        图 1 显示了随着 "猴子 "事件数量的增加而实现的平均 RAC。我们注意到,随着仿真时间的增加,平均 RAC 在 126 秒内迅速增加到 76.5%。之后,增加的幅度就比较平缓了--即使花费 250 秒生成 10K 个 Monkey 事件,RAC 平均也只增加了 1.5%。因此,我们选择运行仿真 126 秒(=2.1 分钟,相当于 5K 个 Monkey 事件),以获得相当的 RAC(76.5%)。换句话说,与执行 100K 个 Monkey 事件相比,我们选择牺牲一小部分(9.5%)的 RAC 来减少一大部分(94%)的仿真时间。

        此外,图 2 还描述了在模拟一个应用程序时发生的 API 调用次数。一般来说,5K Monkey 事件会触发数千万次 API 调用,即一个 Monkey 事件平均会触发 8,460 次 API 调用,这表明在运行 Android 应用程序时,API 的使用非常密集。此外,如图 3 所示,当我们在不跟踪任何 API 的情况下运行应用程序时,平均耗时仅为 2.1 分钟。但当我们跟踪所有 50,000 个 API 的使用情况时,由于拦截大量 API 调用的开销,耗时将大幅增加到平均 53.6 分钟。显然,跟踪所有 API 在时间上是不可行的。我们将在第 4.4 节中研究如何明智地选择 API 的子集。

        机器学习分类模型。与第 3 节中介绍的大多数现有工作一样,我们采用机器学习方法将应用程序分类为恶意软件或非恶意软件。在对数据集中的每个应用程序进行仿真时,我们会记录所跟踪 API 的调用数据(API 调用的名称和参数)。我们采用 One-Hot 编码将日志转换为由 n 个比特组成的特征向量,其中 n 是跟踪 API 的总数。每个比特对应一个被跟踪的 API--如果 API 被调用,则相应的比特被设为 1,否则为 0。我们所研究的应用程序的所有特征向量都被用作训练集和测试集(当然这两个集是不相交的)。

        评估机器学习模型有三个关键指标:精确度、召回率和训练时间。精确度和召回率的定义是:精确度 = TP/TP+FP 和召回率 = TP/TP+FN ,其中真阳性(TP)表示被正确分类为恶意软件的应用程序数量,而假阳性(FP)和假阴性(FN)分别表示被错误识别为恶意和良性的应用程序数量[29]。

        按照惯例,我们计算精确度和召回率来评估恶意软件的检测结果。我们总共使用 scikit-learn [23] 实现了九种主流机器学习模型(参见第 4.2 节)。在我们的实验中,每个模型的超参数都是根据我们的领域知识配置的。

        此外,在评估 ML 模型时,我们采用 10 倍交叉验证,以减少训练和测试阶段可能出现的数据泄漏 [24]。这里的数据泄漏指的是训练集获得了测试集的访问权,即两个集中存在相同或相似的数据,从而导致夸大的评估结果。与单一的随机训练/测试分割相比,10 倍交叉验证通过使用多个不同的训练/测试分割对模型进行训练和测试,使我们能够获得较少偏差的结果。同时,在交叉验证的每次迭代中,我们都会从测试集中删除训练集和测试集中的重复特征向量。此外,我们还检查了训练集和测试集中克隆应用程序(即具有相同软件包名称但不同 MD5 哈希代码的应用程序,这也可能导致数据泄漏)的百分比,发现其相当小(<1%)。具体的模型配置发布于 https://apichecker.github.io/。

4.3 了解选择应用程序接口的权衡因素

        我们使用上述动态分析引擎来评估 API(特征)选择与恶意软件检测时间/检测准确性之间的权衡。首先,我们根据应用程序与恶意软件的相关性对所有 5 万个 API 进行排序[30]。接下来,我们从分析时间、基于 ML 的分类模型、恶意软件检测准确率和 API 选择策略等方面获得了一系列启示。

        应用程序接口与应用程序恶意程度的相关性。API 与应用程序恶意程度之间的相关性是一种客观的统计测量指标[35]。本文使用斯皮尔曼等级相关系数(SRC [30])来评估统计相关性。利用动态分析结果,我们计算了每个 API 与应用程序恶意程度的 SRC 值,并将所有提取的 API 按其 SRC 值从高到低排序,如图 4 所示。我们发现有 247 个 API 的 SRC 值≥ 0.2,2,536 个 API 的 SRC 值≤-0.2。请注意,当某一特征的|SRC|小于 0.2 时,它被认为与应用程序的恶意程度关系很弱或没有关系[36];换句话说,当|SRC|≥ 0.2 时,相关性被认为是不重要的。

        在上述 SRC 大于 0.2 的 247 个应用程序接口中,我们发现其中一些与某些应用程序相互关联,因此在用于分析这些应用程序时有些多余。尽管如此,这些应用程序接口往往在功能上相互补充,而不是相互替代。因此,它们实际上对我们的分析是有益和必要的。此外,当我们仔细研究 SRC 小于-0.2 的 2,536 个 API 时,我们注意到其中大多数 API 很少被数据集中的应用程序调用。在此,我们根据经验将 "很少 "定义为被数据集中少于 0.1% 的应用程序调用。使用这些不常调用的 API 作为特征可能会给机器学习带来过拟合问题,因此我们在进行 API 选择时不得不忽略这些 API。另一方面,我们也观察到,SRC≤-0.2的13个API被大多数应用程序频繁调用,以执行文件I/O等常见的Android操作;在我们的分析中,这些API仍被考虑在内。具体而言,图 5 显示了前 1K 个框架 API,这些 API 的 |SRC|s 被应用程序恶意调用的次数并不少。从图中我们可以发现,有 260 个应用程序接口(247 个 SRC≥0.2 的应用程序接口和 13 个 SRC≤-0.2 的应用程序接口,称为 Set-C)拥有非小的 |SRC|。

        分析时间。图 6 显示了跟踪的 API 数量(n)与分析时间(t)之间的关系,此时我们优先跟踪不常调用的高度相关 API(与应用程序的恶意)。

        为了理解图 6 中展示的统计关系,我们提出了一个复杂的三态分布,并发现它能很好地拟合数据。具体来说,当 n∈[1, 800]时,t 首先随 n 线性增长,相关 API 的使用频率适中,由于其 SRC 较高,更有可能被恶意软件使用。然后,当 n∈[800, 1K] 时,t 多项式增长,这是因为注册的 API 同时被恶意软件和非恶意软件大量使用,因此它们在描述恶意行为方面的表现力较弱。最后,当 n > 1K 时,t 会呈对数增长,因为新添加的 API 的调用频率较低。我们使用以下三模态分布来拟合 t(n):

其中 a1 = 0.006,b1 = 2.06,a2 = 10-9,b2 = 3.44,a3 = 6.4,b3 = -43.36。此外,我们还采用判定系数[34](用 R2 表示,范围在 0 到 1 之间)来衡量测量数据与三个拟合方程之间的接近程度。我们计算出 R2 1 = 0.96、R2 2 = 0.99 和 R2 3 = 0.99,非常接近 1.0(完美拟合)。

        上述结果表明,API 的 SRC 与其调用频率(以及由此产生的动态分析开销)之间的关系相当复杂。定量地理解这种关系有助于更好地平衡分析时间与检测准确性之间的权衡。关于前者,图 6 显示,使用我们的动态分析引擎,最多可跟踪前 490 个 API,实现每个应用程序的平均检测时间少于 5 分钟。我们将很快探讨后者(准确性维度)。

        机器学习模型。我们评估了第 4.2 节中介绍的九种机器学习模型的影响,假设跟踪了所有 50K API。表 2 列出了每个分类器的性能和开销。我们发现,这些分类器在精确度、召回率,特别是训练时间方面表现出显著差异;但是,没有一个分类器在所有三个关键指标上都达到最佳。因此,我们选择采用能在三个指标之间取得最佳平衡的分类器,即随机森林分类器,它能获得最佳精度、较好召回率和可接受的训练时间。此外,众所周知,RF 还具有良好的泛化能力[28]。事实上,当我们只跟踪前 1K 或前 490 个 API(参见图 6)来收集数据时,我们的最佳选择仍然是随机森林分类器。

        恶意软件检测的准确性。跟踪所有 50K API 虽然最耗时,但应该能获得最佳准确率。图 7 显示了基于随机森林分类器跟踪前 N 个相关 API 所达到的检测准确率。跟踪 50K 个 API、前 1000 个相关 API 和前 490 个相关 API 所实现的精度/召回率分别为 91.6%/90.2%、94.7%/92.0% 和 96.3%/92.4%。出乎我们意料的是,(从战略上)跟踪较少的 API 比跟踪所有 50K API 的精确度和召回率要高。深入研究后,我们发现这种反直觉的观察结果源于这样一个事实,即大多数 API 很少被 Android 应用调用,因此过多的特征会导致训练模型过度拟合。换句话说,跟踪较少的应用程序接口可以在运行时性能和检测准确性方面带来好处。

4.4 关键应用程序接口选择策略

        现在,我们将详细介绍我们有原则的应用程序接口选择方法,该方法包括四个步骤。

        步骤 1.选择与恶意软件相关性最高的 API(Set-C)。我们在第 4.3 节中的分析表明,跟踪前 260 个高度相关的 API(Set-C)可实现 93.5% 的精确度和 82.1% 的召回率。

        步骤 2.选择与限制权限(Set-P)相关的应用程序接口。为了保护用户信息的隐私/安全,应用程序在获取某些信息或实现某些功能之前需要请求权限[43]。安卓权限分为三个保护级别[41]:正常、签名和危险。受危险级权限保护的 API 和受签名级权限保护的 API 通常与用户敏感数据(如摄像头、短信和位置数据)相关,因此对恶意软件检测至关重要。我们利用 Axplorer [12] 和 PScout [13] 工具来选择与限制性权限相关的 API,总共得到 112 个 API(简称 Set-P)。仅通过跟踪这 112 个 API,我们就获得了 95.1% 的精确度,但召回率却相当低(71.3%)。

        步骤 3.选择执行敏感操作的 API(Set-S)。第三种策略是选择执行敏感操作的 API。与权限不同,敏感操作没有 "官方 "定义。根据以往的工作,我们发现有五类敏感操作通常会被利用来实施攻击:(1)可导致权限升级的 API,如 shell 命令执行 API [25];(2)数据库操作和文件读/写 API,这些通常会被用于隐私泄露攻击 [14];(3)对关键 Android 组件进行操作的 API,如创建 Android 窗口或覆盖的 API [16];(4)对关键 Android 组件进行操作的 API [17];(5)对关键 Android 组件进行操作的 API [18];(6)对关键 Android 组件进行操作的 API [19]、(4) 加密操作 API,常用于勒索软件攻击[48];以及 (5) 动态代码加载 API,可在运行时加载恶意有效载荷并执行更新攻击等攻击[25]。根据我们的领域知识,我们确定了与上述敏感操作相关的 70 个 API(称为 Set-S)。仅跟踪这 70 个 API,我们就能达到 95% 的精确度,但恶意软件检测的召回率却很低(70.1%)。

        

        步骤 4.综合上述策略。最后一步是综合上述策略,即 Set-P Ð Set-S Ð Set-C,从而得到总共 426 个关键 API。直观地说,这样做既考虑了数据的统计观察结果,也考虑了对手基于领域知识的一般意图。请注意,如图 8 所示,三个集合中只有 16 个重叠的 API,这表明三个集合趋于正交。

        图 9 显示,当我们只跟踪 426 个关键 API 时,每个应用程序的平均耗时为 4.3 分钟,比我们的动态分析引擎的 53.6 分钟(跟踪所有 50K API 时的平均耗时)和接近 2.1 分钟(不跟踪任何 API 时的平均耗时)短得多。在第 5.1 节中,我们将通过设计底层动态分析引擎进一步缩短检测时间。

        此外,我们还评估了九种主流分类器使用 426 个关键 API 检测恶意软件的精确度和召回率。如表 2 所示,随机森林仍然表现出最高的精确度(96.8%)和召回率(93.7%),而且其训练时间(14.4 秒)比更复杂的分类器(如 DNN 和 SVM)要快得多。相比之下,如图 7 所示,仅跟踪前 426 个高度相关的 API(扩展 Set-C,也使用随机森林)的精确度为 95.2%,召回率为 90.6%。这证明混合策略优于单个策略。

        值得注意的是,我们选择的 426 个关键 API 可能不是检测准确率最高的最佳 API 集。由于搜索空间太大,我们并没有穷尽搜索这种 "最优性"。不过,我们提出的 API 选择策略易于执行,并在实际部署中取得了良好效果(第 5.2 节)。

4.5 进一步丰富特征空间

        通过检查 50 万个应用程序的动态分析结果,我们注意到单纯依靠框架 API 来检测恶意软件本身就有局限性:攻击者可以通过其他机制绕过某些关键 API 的调用。在实践中,有两种替代方法可以在不明确调用特定框架 API 的情况下触发其动作:(1)内部/隐藏 API,可以使用 Java 反射等特殊方法触发;(2)intents,Android 的一种关键 IPC 机制,可以帮助应用程序请求另一个应用程序/服务代表它执行敏感动作,以及监控/拦截系统级事件或广播[16]。我们注意到,恶意应用程序会积极利用这两种情况来隐藏对某些应用程序接口的使用。因此,这些 "隐藏 "的 API 调用成为值得进一步探索的隐藏特征。

        幸运的是,我们发现这一限制可以在不产生任何动态分析开销的情况下得到有效缓解。具体来说,我们添加了两个辅助功能来帮助揭示隐藏的应用程序接口调用:请求的权限和使用的意图。请注意,请求的权限是调用内部/隐藏 API 的先决条件--据我们所知,应用程序无法绕过它[16]。这两个辅助特征可以通过分析应用程序元数据和 Set-S 中已跟踪的意图相关框架 API 的参数来收集。具体来说,我们会在现有的特征向量中为每个权限/意图添加一个特征

        图 10 显示,结合使用权限和 426 密钥 API("A+P")可将召回率从 93.7% 提高到 96.5%,而结合使用意图和 426 密钥 API("A+I")可将召回率提高到 94.8%。有趣的是,单独使用权限和意图("P+I")也能实现良好的性能(97.5% 的精确度和 94.6% 的召回率),这意味着这两种机制被当今的安卓恶意软件大量使用。最后,与纯粹使用 426 个关键 API("A")相比,联合利用所有三个特征类别("A+P+I")取得了最佳性能,即精确度从 96.8% 提高到 98.6%,召回率从 93.7% 提高到 96.7%,F1 分数从 95.2% 提高到 97.6%。这里的 F1 分数是精确度和召回率的调和平均值:2 × 精确度×召回率 精确度+召回率 。

5 系统开发

        在第 4 节上述研究成果的指导下,我们实施并部署了 APICHECKER 系统,以自动检测提交到 T-Market 的恶意应用程序。在第 5.1 节中,我们介绍了对仿真环境的优化,以提高动态分析的效率。然后,我们将在第 5.2 节介绍 APICHECKER 的部署及其 "实际 "性能。我们将在第 5.4 节讨论该系统的其他一些实用方面。

5.1 仿真环境优化

        在获得所需的功能之后,我们将重点转移到提高 APICHECKER 的运行性能上。首先,我们注意到默认的谷歌安卓设备仿真器[5]性能并不理想,因为它是在 QEMU [11]基础上构建的重量级全系统仿真。对于我们在第 4 节中所做的实验室内分析,这可能不是问题。但是,在现实世界的生产环境中,需要大规模检查大量应用程序,较长的检测延迟可能会对应用程序开发人员的体验和积极性产生负面影响,并增加应用程序市场运营商的基础设施成本。

        在图 9 中,我们注意到,对于 30% 的应用程序,我们最初的动态分析引擎(第 4.2 节)扫描每个应用程序需要 5 分钟以上,这是 Google Bouncer [26] 的典型周转时间。为了提高扫描性能,除了第 4 节中介绍的检测引擎层面的各种优化外,我们还对底层仿真环境进行了系统级优化。我们构建了一个轻量级仿真系统,可在功能强大的商品 x86 服务器上高效运行 Android 操作系统和应用程序。首先,对于 Android 操作系统,我们使用 Android-x86 [21],它是基于 ARM 的原始 Android 操作系统的开源 x86 移植。因此,ARM 和 x86 之间的 ISA 差距导致的操作系统级性能下降在很大程度上得以避免。同时,为了支持使用 Android 原生库的应用程序,我们利用英特尔开发的最先进的动态二进制转换框架(Houdini [22])将应用程序的 ARM 指令转换为 x86 指令,因为 Android 中的大多数原生库都是基于 ARM ISA 而不是 x86 [47]。

        我们的轻量级安卓模拟器可与 Monkey 和 Xposed 挂钩工具配合使用,并在一台物理 x86 服务器上运行,该服务器配备 5×4 核 Xeon CPU @ 2.50 GHz 和 256-GB DDR 内存。为了充分利用硬件资源,我们在服务器上并行运行多个仿真器,每个仿真器绑定一个 CPU 内核。具体来说,16 个仿真器在 16 个内核上并发运行,其余 4 个内核用于任务调度、状态监控和信息记录。

        虽然我们的轻量级分析引擎大大超越了原有引擎,但其与安卓应用程序的兼容性却略有下降。通过定制 Android-x86 中的 SystemServer 服务,一旦应用程序在仿真过程中挂起或崩溃,异常消息就会自动报告给用于任务调度、状态监控和信息记录的 4 个内核(物理服务器上有 20 个内核)。从收集到的报告中,我们发现有很小一部分(< 1%)应用程序无法在轻量级引擎上成功运行,主要原因是 Android-x86 和英特尔 Houdini 的兼容性问题。对于这些不兼容的应用程序,我们回滚到默认的谷歌安卓模拟器来成功分析它们。这显然需要更长的分析时间,但却确保了 APICHECKER 的可靠性--所有提交的应用程序都可以在我们的生产系统上进行测试。

        上述定制基础架构使 APICHECKER 能够更高效地分析应用程序,在相同硬件和检测引擎配置下,与使用默认谷歌 Android 模拟器相比,可节省约 70% 的检测时间,且不会造成任何检测精度损失(我们已考虑到处理不兼容应用程序的时间成本)。我们在同一物理 x86 服务器上使用默认的谷歌 Android 模拟器和我们的轻量级模拟器评估了每个应用程序的动态分析时间。这里我们只跟踪 426 个关键 API。图 11 显示,在同一服务器上,我们的轻量级模拟器大大节省了每个应用的分析时间。与谷歌安卓模拟器的 4.3 分钟相比,每个应用程序的平均分析时间短至 1.3 分钟。

5.2 系统部署和性能

        我们将优化后的模拟器应用于 APICHECKER,并评估其在 T-Market 中的性能。其中,我们发现一些关键功能发挥了更重要的作用,并对其进行了详细讨论。此外,随着新应用程序的出现和安卓 SDK 的升级,所选的关键 API 需要不断演进,这也促使我们定期更新检测模型。

集成到真正的应用市场。APICHECKER 部署在 T-Market,自 2018 年 3 月起开始运行。它使用单个商品服务器,在 16 个内核上同时运行 16 个模拟器,每天检查约 10K 个应用程序(详细硬件/软件配置请参阅第 4.2 节和第 5.1 节)。

        具体来说,它将应用程序的 APK 文件作为输入,然后将其安装到空闲的安卓模拟器上。接下来,APICHECKER 执行应用程序,同时记录一系列信息作为其特征(第 4 节)。最后,随机森林分类器根据特征向量确定应用程序的恶意程度。整个过程平均耗时 1.92 分钟,其中应用安全分析耗时 1.4 分钟。在随后的 12 个月中(从 2018 年 3 月到 2019 年 2 月),APICHECKER 每月检测到约 2.4K 个可疑应用程序。为了评估 APICHECKER 在生产环境中的检测准确性,我们根据 T-Market 应用程序审查流程中的其他组件(基于签名的初步检测、T-Market 根据用户和开发人员的反馈进行的人工检测,见第 2 节)以及我们自己的人工检查,对提交的应用程序进行检测。这种检测过程可以确保非常高的精确度和召回率,但需要大量的人工操作。结果表明,在 12 个月中,每月的精确度超过 98%(最低:98.5%,最高:99.0%),召回率超过 96%(最低:96.5%,最高:97.0%),如图 12 所示。

        如第 4.1 节所述,T-Market 拥有一套精密的应用程序审核流程,具有极高的精确度和召回率。这使我们能够深入理解 APICHECKER 产生的 <2% 的误报率和 <4% 的误判率。首先,我们发现这 2% 的误报率(应用程序)都使用了图 13 所示的大量顶级功能。换句话说,这些应用程序在 API、权限和/或意图使用方面与恶意应用程序相似。具体来说,在每天提交到 T-Market 的 1 万多个应用程序中,平均有 800 个应用程序被 APICHECKER 标记为恶意应用程序。其中,通常 90% 以上都是更新过的应用程序,可以根据其以前的版本进行快速审核。因此,要找出误报的应用程序,平均只需对不到 80 个应用程序进行人工检查,对 T-Market 来说产生的开销是可以接受的。因此,我们选择每天通过人工工作主动避免误报应用程序。相比之下,用户报告的 4% 的误报则很少使用排名靠前的功能。我们手动检查了检测日志,发现大部分(87%)假阴性应用程序几乎没有使用我们跟踪的 426 个关键 API。事实上,这些应用程序通常具有相当简单的功能,如显示广告或访问某些网站,而这些功能通常被认为对终端用户构成了 "轻微 "的安全威胁。因此,在收到用户对特定应用程序的投诉时,我们会选择被动地减轻虚假负面应用程序的影响。

        重要特征。在我们从 50 万个应用程序数据集中提取的所有关键特征中,我们询问哪些特征在恶意软件检测中发挥着最重要的作用。在图 13 中,我们列出了前 20 个最重要特征的基尼指数[8],其中包括 7 个关键 API、8 个请求权限和 5 个使用意图。由于基尼指数适合我们训练的随机森林模型,因此我们在此使用基尼指数来量化特征的重要性。就功能而言,这 20 个关键特征可分为三类:

  • 试图获取用户设备的隐私敏感信息,如短信(如 SmsManager_sendTextMessage API3)、电话号码(如 TelephonyManager_getLine1Number 权限)和 MAC 地址(如 WifiInfo_getMacAddress API)。
  • 跟踪或拦截系统级事件,如设备的关键活动(如 RECEIVE_BOOT_COMPLETED 权限)、网络状态变化(如 wifi.STATE_CHANGE 意向)和授予权限(如 DEVICE_ADMIN_ENABLED 意向)。
  • 启用某些类型的攻击,如基于叠加的攻击 [45](例如,需要 SYSTEM_ALERT_WINDOW 权限才能发起 "隐身和匕首 "攻击 [17])。

5.3 系统演变

        在 APICHECKER 运行期间,我们注意到有必要定期更新所选的关键 API;因此,关键 API 的总数并不固定(最初为 426 个)。这是因为 T-Market 的数据库中不断有新的应用程序加入,而且随着 Android SDK 每隔几个月的更新,整个 API 库也在不断变化。

        目前,我们更新关键 API(和重新训练分类模型)的周期根据经验设定为一个月。再训练数据集由从 T-Market 获取的原始数据集(§4.1)和随后提交给 T-Market 的新应用程序组成。新应用程序的恶意标签由 APICHECKER 和人工检查标记,没有误报,但有少量误报。此外,我们选择关键 API 的方法与第 4.4 节所述方法相同。

        图 14 显示,从 2018 年 3 月到 2019 年 2 月,我们选定的关键 API 数量仅在 425 和 432 之间小幅波动。因此,在 12 个月的部署过程中,每个应用程序的检测时间保持稳定。请注意,我们在图 12 中报告了在线结果,其中考虑到了这一重新训练过程。如图所示,关键 API 集的变化仅对在线检测精度、召回率和 F1 分数产生轻微影响,分别为 98.5%∼98.9%、96.5%∼96.9% 和 97.5%∼97.9%。总体而言,上述结果表明 APICHECKER 对 API 演进具有良好的鲁棒性。

5.4 关于其他方面的讨论

在 APICHECKER 的运行和维护过程中,我们也获得了关于该系统其他方面的见解或经验,例如该系统对未来可能出现的知识型攻击者的稳健性、对不希望实施我们定制的基础设施的其他应用程序市场的适用性以及对其他应用程序市场的可扩展性。

APICHECKER 对复杂攻击者有多强大?我们编写了一个脚本来扫描 Android SDK(27 级)的源代码,以了解所选关键 API 的实际覆盖范围。我们发现,虽然 426 个关键 API 在 50K 框架 API 中只占很小一部分(0.85%),但有 4816 个其他 API(9.6%)的实现依赖于它们(即这 4816 个 API 的内部实现使用了 426 个关键 API),因此加起来共有 5242 个 API(10.5%)。因此,如果见多识广的攻击者想通过调整 API 的使用来躲避我们的检测,他们就必须用相同的功能 "重新实现 "相当数量的 API,以取代相关的框架 API,同时小心地避免使用我们添加的辅助功能(第 4.5 节)。这即使不是不可能,也是非常困难和乏味的。对于攻击者来说,更实用的方法是使用 Android NDK。但这也提高了恶意软件开发的门槛。此外,大量使用 NDK 的常用功能本身就是潜在恶意行为的一个指标。

我们能否进一步减少关键 API 集?众所周知,API 的选择对于检测精度、分析时间和系统资源消耗之间的权衡至关重要。图 15 显示,在 426 个关键 API 中,大多数对检测准确性的影响相对较小,但对分析时间的影响较大(见图 6)。图 15 中的结果让我们想到,是否可以进一步利用较小的检测精度损失来换取较大的检测时间改善。我们发现,与使用全部 426 个关键 API(精确度 98.3%,召回率 96.6%)相比,只使用排名前 150 位的关键 API 的 APICHECKER 可以达到类似的检测性能(精确度 98.3%,召回率 96.6%),而每个应用程序的分析时间则大幅减少到平均 2.5 分钟,如图 16 所示。这使得在低端 PC 或虚拟机实例上运行谷歌的安卓模拟器来及时检测恶意软件变得可行。

APICHECKER 可以用于其他应用程序市场吗?将我们的方法应用到其他应用商店并不困难,因为它只需要 APK 文件和一些用于训练的真实数据。此外,大型应用市场可以将其训练好的模型分发给小型市场,这样它们就不需要训练自己的模型了。此外,APICHECKER 只使用成熟的程序分析和机器学习技术,易于实施、部署和维护。

6 结论与未来工作

基于机器学习(ML)的移动恶意软件检测在过去十年中大有可为。然而,到目前为止,我们还没有看到针对大规模应用市场的现实解决方案,而大规模应用市场对当今移动生态系统的成功至关重要。为了找出并克服现实世界中的挑战,我们与一个主要的安卓应用市场合作,实施、部署并维护了一个有效且高效的由 ML 驱动的恶意软件检测系统。该系统通过检查运行时对一小部分策略性选择的应用程序接口的使用情况来检测安卓恶意软件,并通过请求的权限和使用的意图等附加功能进行增强。该系统已在我们的合作市场上运行了一年多,并进行了多项系统级优化,如定制的快速仿真引擎、自动模型演化以及经济实惠的误报/负报缓解等。我们希望我们的测量结果、机制设计、部署经验和数据发布能为社区做出贡献。

未来,我们计划探索进一步改进我们工作的潜在机会。首先,我们注意到,由于 Monkey 的用户界面覆盖率对特征提取有至关重要的影响,它可能会成为我们检测工作的瓶颈。为了使我们的自动用户界面探索机制更加稳健和有效,我们希望采用复杂的软件测试技术,如模糊测试(fuzzing)。此外,在我们目前的设计中,我们利用位向量对提取的特征进行编码,这在实践中既轻便又高效,但可能会丢失某些特征信息(如 API 调用频率)并导致过度拟合。因此,我们希望尝试使用直方图等其他编码技术,以保留更丰富的特征信息。

致谢

我们衷心感谢我们的导师 Jon Crowcroft 教授和匿名审稿人的宝贵意见。我们还感谢李伟志、李洋、吴子鹏和龙海对 APICHECKER 的数据收集和系统部署所做的贡献。这项工作得到了国家重点研发计划(2018YFB1004700)、国家自然科学基金(61822205、61902211、61632020 和 61632013)以及北京国家信息科学与技术研究中心(BNRist)的部分支持。

本文标签: 应用于市场规模恶意机器经验