0 引 言
随着数字经济的迅猛发展,数字化生活已经成为人们生活的重要组成部分。传统的线下交互场景逐渐迁移到网络平台
[1],使得个体需要在数字交互中灵活切换不同角色。例如,为了区分私人社交和工作信息,用户创建了多个微信号。然而,Android系统限制了同一设备上同时运行相同包名应用的能力,普通用户只能通过频繁切换账号或在多设备上登录来实现这一需求,这提高了用户使用的成本,给用户带来了不便,因此引发了应用多开的需求,即在单一设备上同时运行多个应用实例的能力。
系统级的多开方案依赖Android的多用户机制
[2],通过切换账户在不同的用户空间中运行应用,但它无法保证同一应用的多个实例同时运行。一些手机制造商通过修改Framework层实现双开功能,如小米MUMI8系统,这种方案可能无法在其他手机厂商的Android版本上运行
[3]。早期的应用级多开方案通过修改包名或者拦截应用的执行过程实现,但这些方法具有较强的侵入性,需要对应用进行修改和操控,可能会破坏应用的原始逻辑和稳定性
[4]。
目前的主流多开方案主要依赖于Android应用层虚拟化技术。该技术通过在Android应用框架层构建透明的沙箱环境,实现了应用层级别的隔离和虚拟化。通过允许不同应用实例之间共享UID(User ID),有效地解决了Android系统对同一应用多实例同时运行的限制问题。虚拟化层构建于应用框架层之上,能够大幅降低底层系统版本差异对应用适配的影响,从而减少了为不同版本进行专门适配的必要性。其次,该技术通过模拟系统环境动态加载和执行应用程序,确保了应用原有逻辑不受破坏,进一步增强了多开应用的运行可靠性。得益于这些关键优势,基于虚拟化的多开应用已成为当前市场的主流解决方案,如“LBE平行空间”和“双开空间”在Google Play上的下载量均已超过1亿
[5]。
然而,多开环境中应用之间共享UID导致了权限集的共享。为了适配不同类型的应用,几乎所有多开应用都直接申请了超量的权限,平均每个应用申请了129个权限
[6]。这种权限的过度申请和UID的共享增加了用户数据隐私泄露的风险。自2016年以来,利用这类多开技术的安全威胁事件不断增加
[7],Twitter、WhatsApp等许多用户量庞大的应用相继受到攻击
[8-12]。Luo等
[13]揭示了恶意多开应用通过钓鱼攻击目标应用以获取用户登录凭证,并指出多开应用可被广泛用于逃避病毒引擎检测、执行权限提升、无代价网络钓鱼和应用推广欺诈攻击
[14],从而对设备系统的安全构成威胁。此外,研究者们深入探讨了应用层虚拟化框架引入的安全威胁
[5,15-16],并关注到恶意病毒利用该技术重打包应用产生新的变种
[7],如Mascara以附加恶意组件的方式提取受害者手机中的敏感信息
[17]。除了提出新型的攻击方式,研究人员还努力更新反病毒引擎,以帮助良性应用识别虚拟环境和恶意多开应用。通过识别虚拟环境引入的指纹特征
[5,13,15]、分析虚拟化框架的行为差异
[7,18-19]识别虚拟化环境。此外,MARVEL还引入了对多开应用的身份校验机制来抵制新型重打包攻击
[20]。
在基于Android应用层虚拟化框架的多开应用安全研究中,早期的研究主要集中在攻击方面,以揭示多开应用中的安全威胁。随后的研究则进一步提出了对抗和缓解方案,以应对这些安全威胁。然而,现有文献在系统性地评估攻击与防御技术方面存在不足,针对性的解决方案也尚未完善,业界尚未有文献对该领域的研究工作进行全面整理。因此,本文针对Android多开环境中角色的复杂性,深入探讨了安全威胁的来源、不同参与方的潜在攻击手段及其协同作用可能触发的攻击行为,全面分析了多开应用环境下的安全风险;详细列举了由虚拟化框架引入的关键指纹特征,综合评估并对比了现有的多开环境检测技术与安全增强策略;指出了研究中尚未解决的问题,并对未来的研究方向提出了建议。
1 多开应用基本架构
本节将介绍多开环境中的各个参与角色及其交互过程,并阐释实现多开功能的核心技术。这些内容将为第二节中攻击方式的说明提供铺垫和背景。通过深入了解多开环境,可以更好地认识其中的安全挑战和风险,并为后续的探讨和解决方案奠定基础。
1.1 多开环境中的角色协同
基于Android多开应用的技术设计和使用场景,多开环境中主要涉及三个关键角色:容器应用、插件应用和用户。如
图1所示,用户首先启动多开应用,以便对选定的外部应用创建并行实例,多开应用准备就绪后,会承载支持其运行的配套插件以及用户选择的第三方插件。这三方角色是基于用户需求和应用层虚拟化技术的特性而产生的,它们通过扮演不同的角色和功能,共同实现了在同一设备上同时运行多个独立应用实例的目标。
1) 容器应用
容器应用是多开环境的核心组成部分,负责创建虚拟化的运行环境,并有效地承载和管理各个插件应用的实例。借助应用层虚拟化技术和隔离机制,确保各插件应用实例能够实现独立运行。
2) 插件应用
插件应用是加载到多开环境的具体应用实例,用于承载具体的功能需求,包括容器应用配套开发的插件应用和从外部加载的第三方插件应用。插件应用共享容器应用的UID,在权限控制层面被操作系统视为单一实体。为确保系统的运行稳定性,每个插件应用都会被分配一个独立的PID(Process ID),在进程管理上相互独立,一个插件应用的异常不会影响其他插件应用或容器应用的正常运行。
3) 用户
用户作为多开应用的最终使用者,通过容器应用进行插件应用的访问和操作,以满足各类多样化需求。例如,用户可能在同一设备上同时使用多个社交媒体账户、游戏账户或其他应用。多开环境为用户提供了方便,使其能够轻松地切换、管理和使用不同的应用。
1.2 核心技术
Android多开应用的核心技术在于插件应用和系统之间代理层的引入。代理层的作用主要体现在两个方面:一是为插件应用提供了受控的执行环境,拦截和处理它们对系统的访问请求,并管理插件应用的生命周期;二是通过巧妙地接管系统服务,绕过系统对插件应用的验证,以保持其身份隐匿。代理层的主要功能可以分为免安装加载、权限委托、组件生命周期管理、通信协调和存储重定向五个模块。目前,流行的框架如VirtualApp
[21]和DroidPlugin
[22]都采用了类似的实现方式。
1) 免安装加载
在传统的Android系统中,应用需要通过安装过程将完整的应用包部署到设备上,并生成应用对应的DexClassLoader
[23]和包含DexFile的DexPathList,以供系统加载和运行
[24]。相较之下,多开应用采用自定义的类加载器,在安装应用时将插件应用的Dex文件提前复制到私有目录中。通过Hook(技术拦截) openDexFileNative函数的调用,容器应用修改Dex文件路径,并将插件应用的DexPathList整合至容器应用中,实现对容器应用资源的灵活加载。
2) 权限委托
在多开环境中,当插件应用加载时,它会与容器应用共享UID,同时获得一个独立的PID。例如,当用户选择对应用App1进行多开操作时,App1在多开环境中被加载并转换为App1*,它将继承容器应用的UID,但在自己的独立进程中运行,如
图2所示。基于Android系统的权限控制机制,插件应用在多开环境中继承了容器应用的全部权限,即使在没有显式申请的情况下也可以使用,构成了一种权限委托,即插件应用的权限由容器应用进行管理。
3) 组件生命周期管理
为实现对插件应用组件的接管,容器应用会预先注册一系列空壳组件,当加载插件应用时,容器应用会自己创建新的进程,然后将插件加载到该进程中,并将原进程名、组件名等替换成插件相应的信息。通过拦截插件应用和系统服务之间的请求,实现对组件信息的动态更改,通过容器应用中的空壳组件代理插件应用中组件的请求,系统就能够灵活地识别和调用插件应用的组件,实现对组件生命周期的灵活管理。
4) 通信协调
由于插件应用和系统服务运行在不同的进程中,进程间通信(IPC)
[25]成为维护插件应用正常运行的必要环节。在实现对插件应用的组件生命周期管理中,多开应用Hook了Android系统的关键生命周期函数,包括启动新的Activity、绑定和解绑Service、管理各个组件的生命周期、注册和注销广播接收器以及处理配置变化等关键函数。并通过Hook IPC干预关键的生命周期事件,从而灵活地管理插件应用中各个组件的运行状态,确保其在虚拟环境中能够正常运行。这一机制使得插件应用能够巧妙地绕过原始系统的组件注册限制,嵌入到多开应用的容器环境中。
5) 存储重定向
Android应用使用独立的私有存储空间,以UID为标识实现隔离。通常情况下,关键代码和数据存储在内部私有目录,即路径为/data/data/包名/。为了更有效地管理插件应用资源,容器应用通过拦截底层文件操作函数(如open()、mkdir()),将插件的安装目录重定向到容器应用的子目录下,实现了代码的存储重定向。这绕过了Android系统的数据隔离和访问控制,使得容器应用能够更好地管理插件应用的数据。
2 多开应用安全威胁分析
Android多开应用为用户提供了同时运行多个应用实例的便利功能,但其背后的复杂机制也引入了一系列安全威胁。多开环境中参与角色的多样性及其攻击能力的异质性,进一步加剧了安全威胁的不确定性。攻击者通过利用不同角色的攻击潜能,能够发起更为精细和隐蔽的攻击行为,这可能对应用安全、用户隐私和系统稳定性造成广泛影响,并可能引发包括隐私泄露、恶意功能部署和资源滥用在内的多种安全问题。本文通过深入分析多开环境中各个角色的潜在攻击能力,并充分考虑角色间的交互作用,系统地评估由不同角色及其协同作用可能引发的安全风险。
2.1 多方角色的攻击潜能
Android多开应用的设计引入了一系列环境特有的风险,这些风险赋予了参与角色多样的攻击潜能。首先,容器应用的完全控制权可能使其隐匿恶意行为,从而难以被有效监控和识别。其次,多开环境内的应用共享相同的UID,削弱了Android系统的权限管理效能,为恶意攻击者提供更大的攻击面。此外,用户在多开应用中享有较高的自主权,这增加了用户行为的不可控性。恶意参与方的存在不仅威胁到其他参与方的利益,也可能破坏设备系统安全和社会业务秩序的稳定。
表1展示了Android多开应用设计所带来的风险来源,以及这些风险如何赋予不同角色特定的攻击潜能。下文将详细分析这些角色在被恶意利用时可能表现出的潜在攻击能力。
1) 恶意容器应用
恶意容器应用指具备恶意意图的多开应用,通常选择受欢迎的应用进行伪装,模仿其外观和功能,欺骗用户执行恶意行为。恶意容器应用能加载运行插件应用、监视应用运行状态和Hook特定的调用等。恶意容器利用对多开环境的完全控制能力,植入恶意代码,运行也不易被用户和系统感知,用户隐私、应用安全都受到了极大的威胁。
2) 恶意插件应用
恶意插件应用分为恶意容器应用的配套插件和独立的第三方恶意插件。由于多开环境内部隔离机制的不足,它们能对内部应用的数据、资源和代码进行操作,从而实现数据窃取、广告注入、勒索攻击以及用户身份盗窃等目的。
3) 恶意用户
恶意用户指具有恶意意图的个人或组织。他们可能与恶意容器应用协同进行攻击、欺诈或违法行为,对应用开发者的利益造成侵害。同时,恶意用户还能通过多开应用执行大量计算或网络请求,降低目标系统性能或引发系统崩溃,对设备的系统稳定性造成破坏。
2.2 多开应用中的攻击方式
在Android多开环境中,容器应用绝对控制权的拥有、插件应用恶意功能的实施,以及用户自主选择权的滥用,均是潜在的安全风险因素。攻击者利用多方角色的攻击能力差异,通过角色间的协同配合,能够发起更为复杂和更具针对性的攻击。本文从恶意参与方出发,深入探讨了不同角色协同可能构成的多种攻击方式以及对应的攻击目的、受影响的实体和预期的攻击结果。通过全面评估不同角色及其协同作用可能引发的安全风险,为进一步的防御提供指导。
2.2.1 新型重打包攻击
新型重打包攻击是指利用多开技术隐藏恶意代码、逃避恶意引擎检测的方式
[7]。攻击者将恶意代码作为插件应用在多开环境中免安装运行,使得恶意代码更具隐蔽性,难以被引擎检测和用户感知。它绕过了传统恶意软件开发所需面对的诸多困难,如逆向工程、用户诱导、应用市场欺骗等,因此被广泛用于恶意软件的重打包
[16]。Zheng等
[14]开发的Z4Plugin工具能够将任何恶意APK文件转换成能够绕过VirusTotal所有引擎检测的新APK文件,展示了新型重打包攻击的一种实现方式。Zhang等
[15]的研究揭示了恶意软件利用虚拟化技术作为简易的重新打包机制的趋势。Dai等
[16]在现实环境中识别出多个案例,证实了利用虚拟化技术进行恶意打包的行为是切实存在的。Shi等
[7]开展了广泛的大规模调研,并设计了有效的检测与缓解措施,以对抗这一新型攻击。他们的研究表明,基于虚拟化技术的重打包攻击已经超过传统重打包应用的数量,并且仍在不断增长
[7]。
新型重打包攻击常将恶意容器应用与配套恶意插件应用整合为独立系统,例如基于DroidPlugin开发的恶意软件Triada变种
[11],它伪装成豌豆荚引诱用户安装,使用远程服务器控制插件的加载,这些插件执行各种活动,包括连接WiFi信号、记录通话、获取位置、发送消息、上传私人数据和更新自身。这些插件在后台运行,不显示任何界面,使Triada能够秘密执行恶意活动。其攻击流程主要包括三步:
1) 恶意代码隐藏:攻击者首先需要开发包含恶意功能的插件应用,并对其进行加密,以逃避静态检测。具体操作是在运行时从容器应用的子目录导入(例如PluginPhantom
[9])或者通过互联网下载恶意插件(例如Hummingbad
[10]),然后进行动态加载和执行。通过将不同的恶意功能解耦到多个应用中,减少单个应用的恶意性特征,从而为恶意代码的识别增加难度。
2) 社会工程学欺骗:攻击者通过虚假广告、欺诈性页面或恶意链接等社会工程学手段,诱使用户下载并安装看似正常的应用,使得恶意容器应用通过伪装成功安装到用户的设备上。
3) 恶意功能执行:一旦用户运行恶意容器应用,攻击者会通过该容器应用加载恶意插件模块。这些插件模块可能包含各种恶意功能,如窃取信息、广告注入、远程控制等,以实现攻击者的恶意目的。
这种新型重打包攻击使攻击者能够广泛传播恶意软件,甚至对用户设备和系统造成严重威胁。在谷歌安全团队删除基于DroidPlugin的恶意软件变种HummingBad之前,被感染的20个Android应用程序的下载量已经超过1 200万次
[26]。
2.2.2 应用劫持攻击
应用劫持攻击是指恶意容器应用篡改或劫持目标应用的行为。恶意容器应用通过对其内部的完全控制能力,实现对应用的静默加载,并轻松监视插件应用的运行状态,进一步篡改应用行为,注入恶意功能,包括界面篡改、输入监听、广告注入、功能重定向等。这些攻击手段使得恶意容器应用能够深度介入目标应用,扰乱其正常行为,甚至窃取用户敏感信息或执行其他恶意活动。最新的Mascara
[17]通过伪装成合法应用的插件形式欺骗用户安装,执行恶意代码劫持用户输入,并逃避已有的虚拟化环境检测执行攻击。
一方面,恶意容器应用与其配套插件协同配合,展开针对性的网络钓鱼攻击
[16]。以DualTwitter
[8]为例,该应用基于VirtualApp框架
[21]开发,攻击方式如
图3所示。它通过嵌入VPN服务,诱使用户安装,同时加载恶意代码,监听用户在Twitter登录窗口的输入,以窃取用户登录凭据。这种劫持手段的危害在于其具有高度欺骗性,用户难以察觉,且这种钓鱼活动实施的代价较低。Zhang等
[15]曾对支付宝进行了类似的攻击,攻击者通过调用系统服务接口获取前台应用信息,在支付宝启动时弹出透明的网络钓鱼窗口,覆盖顶部活动,捕获用户输入(如付款密码),并将其发送至远程服务器。这种攻击手段巧妙地利用系统接口和用户交互盗取了用户的敏感信息。此外,恶意容器应用还可以通过自启动广告获取CPI(Cost Per Install)广告的利益
[14],甚至干扰Android系统中其他应用的运行流程,静默加载到虚拟环境中进行应用劫持。
另一方面,恶意容器应用可以与恶意用户协同,破解应用的付费机制或进行网络欺诈活动
[27-28]。通过修改应用的验证逻辑、篡改付费验证请求或者操纵应用的本地存储数据等方式来欺骗应用,绕过应用内购或订阅机制,获取应用内的付费功能而无需支付费用。这种破解行为不仅损害了应用开发者的商业利益,还可能导致应用生态系统的不公平竞争。恶意用户还可以利用多开应用进行各种欺诈活动,如虚假投票、刷榜和刷单等,获取不当利益,甚至扰乱正常业务秩序。
2.2.3 中间人攻击
许多多开应用会内嵌应用市场,提供便捷的应用搜索、下载、安装和更新服务。然而,一些虚拟化框架内部使用未加密的HTTP链接进行应用下载,这增加了中间人攻击的风险
[15]。攻击者通过干预应用市场和用户之间的通信,可篡改应用的下载链接或应用包,如Hook startActivity函数,拦截插件向应用安装程序发送的Intent并修改通用资源标识符(URI),导致用户可能下载安装被篡改的应用,其中可能包含恶意代码或后门
[28]。这样的中间人攻击破坏了通信的机密性和完整性,潜在地引入了安全风险。
2.2.4 权限提升攻击
多开应用中的权限提升攻击
[6,15-16]来源于应用间的权限共享与重用,导致了Android原有权限机制的失效。应用在Android系统中运行时需要在其Manifest文件中定义所需权限,然后在运行时根据声明的权限由用户动态授权,实现对应用的权限管理
[29]。插件应用可以在未经用户授权情况下重用多开应用所申请的权限,因此引入了零权限应用威胁
[14]。以App1和App2为例,这两个插件应用都运行在同一多开应用中。如果用户在多开环境中拒绝了App1发送短信的权限,但批准了App2的相同权限,App1便能间接使用App2的权限,通过容器应用的内部机制发送短信。这种权限共享机制可能被滥用以执行更复杂的攻击。例如,攻击者可能设计App1在后台静默定位用户、拍照、录音或读取通讯录和短信,而用户可能对此毫无察觉。利用这些敏感API,App1能够搜集并可能外泄大量个人信息,转变为具有高度危险性的恶意软件。
2.2.5 数据滥用攻击
数据滥用攻击
[6]来源于多开应用中内部应用访问控制机制的缺位。现有的访问控制机制大多简单粗暴、易被绕过,从而难以抵御各种攻击
[6]。恶意插件应用通过充分利用插件间数据访问缺陷,对其他应用的内部存储数据执行多种操作,包括访问、删除、加密和复制等,以实施各种恶意活动。尽管一些应用已加强了访问控制策略,但这些策略多数过于简单,容易被相对攻击和链接攻击等手段绕过
[15]。数据滥用攻击的攻击目标主要有以下三类。
1) 隐私数据窃取
[16]:插件应用之间没有数据隔离,可以任意访问彼此的文件,恶意插件应用可以在不声明所需权限的情况下执行活动,窃取其他应用私有目录下的敏感数据。研究者们成功模拟恶意插件应用,对微信的敏感文件进行了窃取
[6,15],Zhang等
[15]读取出用户账号信息和设备信息生成密钥,基于微信开源的加密算法还原出纯文本的用户聊天记录。
2) 勒索软件攻击
[16]:恶意插件应用可以通过加密或删除关键文件的方式对其他插件应用发起攻击。在这种情况下,攻击者会加密或删除其他插件应用的关键文件,然后向用户勒索一定数量的赎金以恢复这些文件。这种勒索行为对用户和插件应用的安全构成直接威胁,可能导致数据丢失、服务中断,甚至经济损失。
3) 数据克隆攻击
[16]:攻击者利用恶意插件应用,将目标应用程序在运行时生成的数据文件上传至远程服务器,以此绕过身份验证机制。攻击者通过在多个实例中复制或克隆数据来获取敏感信息或破坏系统正常运行。这种攻击手段可导致恶意插件应用非法获取其他应用的敏感信息,进而可能滥用用户数据或执行未经授权的操作。攻击者利用数据克隆可成功窃取Facebook本地存储的登录令牌
[15],将其传输到远程服务器,然后通过替换受害者本地应用的令牌,实现在Facebook上滥用其账户。
2.2.6 代码注入攻击
许多插件应用可能会在运行时加载存储在其私有目录中的可执行文件(如.dex文件、.jar文件、.so文件等),恶意插件应用通过篡改或替换这些文件,实施代码注入攻击
[6,16]。这种方式使得恶意插件得以注入恶意代码到其他应用的运行过程中,从而执行各种危险操作,如窃取用户敏感信息、监控应用行为等。代码注入攻击可能导致目标应用的安全漏洞、数据泄露,甚至影响整个系统的稳定性。
2.2.7 资源耗尽攻击
多开应用中资源耗尽攻击的根本原因在于用户行为的不可控。由于多开应用的特性,用户可以在多个应用实例中同时执行大量计算任务或发起大规模的网络请求,系统资源被迅速消耗殆尽
[3]。这种攻击方式利用了多开应用的灵活性和并发性,使得恶意用户能够在短时间内对目标系统施加巨大的负载,使其陷入性能下降或崩溃的境地。
表2全面地总结了多开环境中的攻击方式,揭示了攻击者行为的多样性及其对系统安全的广泛影响。在角色协同方面,新型重打包攻击、应用劫持攻击、中间人攻击涉及多个角色的合作,使得攻击策略更为复杂和隐蔽。恶意容器应用与插件的协同合作可能导致应用劫持、数据滥用和权限提升攻击,这些攻击手段通过深度介入目标应用,扰乱其正常行为,可能导致用户敏感信息泄露、应用功能被滥用等风险。恶意用户可能与恶意容器应用协同来破解付费功能,侵害应用的版权利益等。
从攻击结果来看,新型重打包攻击、中间人攻击以及资源耗尽攻击直接影响系统安全和稳定。新型重打包攻击和中间人攻击通过不同手段植入恶意软件,而资源耗尽攻击可能导致系统性能下降甚至引发崩溃。代码注入攻击和新型重打包攻击则可能引入严重的恶意攻击。网络钓鱼攻击和数据克隆攻击则直接威胁用户的在线安全和隐私,通过欺骗性手段窃取用户登录凭据引发隐私泄露和其他安全问题。综合而言,这些攻击方式在威胁程度上存在差异,但它们共同构成了多开应用生态系统的风险。有效的安全措施需要综合考虑这些不同攻击的特点,采取相应的防范策略,以确保用户和系统的安全。
3 防御对抗方法
面对多开应用环境的安全威胁,安全研究人员采纳了“风险识别与防御增强”的策略。本文将该策略细分为三个研究方向:动态检测、静态检测和安全增强。前两者侧重于通过分析虚拟化框架的特征来识别多开环境,而安全增强则旨在通过技术手段和管理策略提升多开环境的内在安全性。鉴于虚拟化框架特征识别在多数方案中的关键作用,本文首先对关键的指纹特征进行了系统化梳理。随后,详细阐述了每个研究方向的防御思路和具体实施策略,并对不同方案的防护时机、特点及效果进行了比较。
3.1 指纹特征
研究者们在虚拟化框架的安全领域进行了深入分析,利用指纹特征检测多开环境
[6,7,13,15]。这些指纹特征包括静态和动态两大类,它们共同构成了识别虚拟化框架的多层次特征集。本文对现有研究成果中发现的指纹特征进行了系统化的整理和分类,具体列举如
表3所示。静态特征侧重于应用的组件构成、路径结构和权限设置,这些信息可通过审查应用的Manifest文件或读取其安装信息获取。相对而言,动态特征则涵盖了应用运行时的内存状态和行为属性变化,识别这些特征往往需要依赖实时监控和动态分析技术。
3.1.1 静态特征
1) 组件。为了实现对插件应用的组件声明周期进行管理,虚拟化框架使用了大量的空壳组件,对插件应用后续注册的组件动态代理。这些组件具有类似的命名结构,通常为应用名、代理标识、代理组件标识与组件序号的组装,因此清单文件中组件名称和组件数量以及组件结构的相似性可以作为指纹特征。
2) 权限。为了确保兼容更多应用,多开应用通常会请求超过正常水平的权限。据调查
[5],多开应用的平均权限申请量为129个,明显高于正常应用。因此,通过对清单文件中的权限请求数量进行统计,可以帮助检测运行环境。
3) 包名。由于插件应用并没有安装到Android系统中,因此可以通过查询PackageManager
[30]获取所有已安装应用的列表,并检查其包是否在该列表中。
4) 路径。插件应用被加载到虚拟环境中后,代码资源被进行了存储重定向,其文件资源作为子目录被移动到了容器应用的子目录下,前缀变长(例如“/data/data/pck_A/Plugin/pck_B”),因此可以通过检查ApplicationInfo的sourceDir字段获取Android应用程序包(apk)的位置
[31]。
3.1.2 动态特征
1) 组件。DroidPlugin在处理广播接收器时存在缺陷,静态广播接收器缺乏对应的代理空壳组件,采用生成代码的动态注册方式。因此,对应用的动态接收器注销后,静态广播器可能无法正常运行,导致错误。此外,它未实例化已禁用的组件,将广播接收器的enabled属性默认设置为false,然后在运行时尝试启用。但当应用作为插件运行时,此启用操作将无效,导致接收器仍然处于禁用状态。
2) 路径。应用在多开应用加载时,动态链接库路径发生变化,Android从“/data/app/package”加载动态链接库路径。通过读取“/proc/self/maps”中的进程内存信息,可以搜索可疑路径的存在,还可用于检查应用的私有存储目录路径信息。
3) 进程。插件应用与多开环境中的其他应用共享UID,Android基于UID实现应用进程隔离。通过进程搜索检查同一UID下运行的进程,如果发现未知进程则说明运行环境异常。有些插件应用的进程名会将容器应用的名称作为前缀。
4) Hook。虚拟化框架为了实现资源加载和组件生命周期的管理,Hook了大量系统函数,并通过自定义native库注入到插件应用进行Hook如“libiohook.so”。因此可以对Hook痕迹进行检测,包括异常堆栈跟踪、内存中可疑动态链接库的识别等。
5) 权限。在Android系统中,应用仅能使用已声明和被授权的权限。虚拟化框架内UID共享导致应用权限共享。为了检测运行环境,可通过访问未声明权限的资源来验证虚拟框架。
3.2 动态检测
前期研究者们主要专注于如何通过检测应用的运行环境来防止其加载到多开环境中。其中两个代表性的工作是PluginKiller
[13]和DiPrint
[6]。它们设计了一系列启发式检测方法,并将其制作成Android SDK库以嵌入应用。在应用启动时,对虚拟话框架进行检测,发现异常则即刻强制结束应用运行。二者均关注到组件注册信息、应用私有存储路径、未声明权限使用等方面的差异。DiPrint增加了对组件生命周期相关函数的堆栈追踪和可疑Hook库的搜查,PluginKiller观察到应用组件在虚拟化框架中解析的差异,例如,DroidPlugin在解析静态广播接收器时会生成动态注册代码,应用使用API unregisterReceiver
[32]注销所有动态接收器,如果发现静态广播无法正常解析,说明运行环境为虚拟环境。
然而,这些防御机制依赖于对通过特定API检索到的虚拟环境属性的分析,这些属性可能容易被利用Hook的恶意容器应用修改。Mascara攻击就绕过这类的虚拟化环境检测方法,并提出通过检查Android运行时环境中记录混合编译的字段值(即ActivityThread类
[33]的hotness值)来检测虚拟环境
[17],他们实验测试发现主流的八款多开应用都采用AoT运行前预编译,对应的hotness_count都为0,因此可以基于这一特征值多开应用进行检测,有研究人员在此基础上结合frida检测恶意虚拟容器
[19]。这种方案虽然避开了对特定API调用的直接检测,但攻击者在掌握相关知识后,仍能轻易篡改或绕过防护机制。
后续研究者提出了更多间接的特征来识别虚拟化框架。例如,PluginAssassin
[18]观察到虚拟环境在插件应用执行期间引入了额外代码,但不同活动启动场景的时间开销不成比例。因此,他们提出根据进程内和进程间活动启动时间比的差异来检测运行环境。然而,这种方法很容易受到系统负载和并发活动的差异导致误报。
尽管动态检测方案能有效识别虚拟化框架的指纹特征,但其实现逻辑通常相对简单,并且经常被部署在应用启动入口,易受攻击者攻击。一旦攻击者获取了相关背景知识,就可以利用容器应用对内部环境拥有的完全控制能力,在运行时拦截和篡改这些检测措施,导致检测失效
[20]。因此,这类检测方案无法有效防御恶意容器应用主导的新型重打包攻击和应用劫持攻击。
3.3 静态检测
针对恶意容器应用主导的攻击,App in the Middle
[15]和VAHunt
[7]提出了静态检测方案,在检测虚拟化框架的基础上进一步判别其恶意性。App in the Middle方案检测是否有50%的组件具有相似的结构和对callApplicationOnCreate()回调函数的覆盖,通过这两个特征来识别虚拟环境,并通过比较容器应用和插件应用之间的证书签名的不一致来判断恶意性。然而,该方法无法检测不加载三方插件的独立系统,且在插件应用apk混淆的情况下可能失效。VAHunt则基于应用层虚拟化框架中的Intent封装机制构建有限状态机,通过检测插件组件是否被空壳组件替换证明虚拟框架的存在。然后利用Flowdroid对路径API和文件对象相关的数据流和函数调用图进行分析,发现了四个加载策略特征来区分框架的恶意性。该方案能够有效防御大部分的攻击,但静态方案的局限性导致被动态隐藏的恶意行为可能无法被发现。
3.4 安全增强
App in the Middle和VAHunt提出的静态检测方案虽可抵御重打包攻击,但它们通常在攻击发生后才采取应对措施。为了更全面、更彻底地防范重打包攻击(包括传统的和基于虚拟化的新型重打包攻击),MARVEL
[20]引入了一种早期介入的保护机制。该方案通过定制VirtualApp设计出可信容器,限制受保护的应用只能在可信容器中作为插件成功执行。在非信任环境中,通过启动反篡改机制保护应用免受恶意容器应用攻击。但是该方法要求用户预先安装可信容器,并对应用注入MARVEL保护、重新打包和签名,修改后的应用也无法在Android原生系统上运行,受到了兼容性和可扩展性的限制,导致其在Android原生系统上的运行和扩展性较差。但是该工作首次引入了可信容器的概念,并且设计了工具来对受保护的应用进行自动化保护生成。
针对多开环境中的权限提升攻击问题,Hsiao等提出了一种更细粒度的权限管控方法PluginPermCheck
[34]。该方法通过监控Intent封装过程,记录应用包名和签名证书以区分宿主与插件应用。它进一步检查应用清单中声明的权限集,并在运行时监控系统服务的权限请求,解析请求的参数得到PID和请求的权限名称,最后与相应PID的权限集对比,从而判断是否应该阻止该权限申请。这种方法通过对Android权限请求函数的申请主体进行检查,有效限制了多开环境中插件应用的权限使用,提高了对权限提升攻击的防御效果。然而,该方法可能受到PID伪造和权限集篡改的影响。
表4列出的多种防御工具展现了不同的安全防护策略和它们在多开环境中的效用差异,
表4的序号与
表3中的指纹特征相对应。其中,PluginKiller
[13]和DiPrint
[14]作为动态检测工具,通过在应用启动时分析组件、路径和权限等特征识别虚拟环境,有效防御权限提升等恶意插件攻击。但它们对抗利用Hook技术的恶意容器攻击存在局限性。PluginAssassin
[18]和Against-Mascara
[19]尝试通过监测进程时间和Android数据结构变化提升安全性,但它们的准确性可能受到系统负载和攻击者绕过策略的影响。为了克服这些局限,研究者发展了静态检测方案,如App in the Middle
[15]和VAHunt
[7],它们在应用运行前通过分析静态信息识别潜在的虚拟化框架,有效抵御了部分重打包攻击。然而,这些方案可能无法及时识别仅在运行时显现的动态攻击。MARVEL
[20]提出的可信容器方案通过VirtualApp构建安全执行环境,并启动反篡改机制,但需要用户预装可信容器,影响了其在Android原生系统上的兼容性和可扩展性。PluginPermCheck
[34]通过监控权限请求来增强对权限提升攻击的防御,但可能受到PID伪造和权限集篡改的影响。总体而言,虽然研究者提出了基于可信容器和动态权限监控的解决方案
[20,34],但这些方法在兼容性、可扩展性或鲁棒性方面仍面临挑战。未来的研究需要在现有方案的基础上,进一步探索如何整合动态和静态检测的优势,并提升多开容器的安全性和用户友好性。
4 现有防御对抗方案的不足
4.1 动态检测存在的问题
动态检测方案分为两类,一类通过API检查指纹特征,而另一类则通过间接特征检测虚拟化框架。这些方法在应用运行时用于检测运行环境,然而,在面对恶意容器应用主导的攻击,尤其是新型重打包攻击和应用劫持攻击时,这些方法存在一些局限性。
1) 难以抵御对抗性攻击:恶意容器应用可能利用对内部的完全控制能力,通过Hook技术绕过动态检测,使得检测方法失效。为应对对抗性攻击,可以加入更复杂的保护技术,如反调试、代码混淆、防Hook技术、运行时环境监测和行为分析。这些技术可提高动态检测代码的抵抗性和识别能力,但需平衡安全性和性能,并需持续研究和更新。
2) 用户体验受损:一些动态检测方案在检测到虚拟化环境后采用直接退出应用的方式,这导致用户无法使用正常的多开应用功能,从而影响用户体验。为了改善用户体验,可以提供多样化的警告方式,让用户了解虚拟化环境可能带来的风险,并提供适当的选择,让用户自行决定是否继续使用应用。
3) 实时性和性能开销:动态检测面临实时性和性能开销的问题。它通常作为依赖库嵌入应用中,需要在应用运行时进行实时监测,这可能在资源受限的移动设备上引起较大的性能开销。为了降低影响,可以通过优化算法、数据结构和代码实现,进行高效的事件触发,只在必要时进行检测操作。这样可以在保证实时性的同时减少性能开销。
4.2 静态检测存在的问题
静态方案在应用运行前分析代码识别虚拟化环境,再进一步通过包签名和隐蔽加载行为等特征判断虚拟环境的恶意性。然而,静态方法容易受到应用采用代码混淆、虚假信息欺骗等手段的规避。由于多开应用的特征模式可能随时变化,这可能影响静态检测的准确性。为了改进静态检测方法,我们可以考虑引入深度学习模型挖掘新的虚拟化环境特征,例如在文件读写、网络传输等方面,从而增强检测的准确性和适应性。引入语义分析来分析代码上下文是一个重要的改进方向,特别是对于隐藏在回调函数中的恶意行为。通过语义分析,可以提供更深入的检测能力,包括对代码逻辑的推理、数据流分析以及对敏感操作的识别等。
4.3 安全增强技术存在的问题
针对虚拟化框架的安全风险,目前对抗方案大多针对虚拟化框架进行检测,少有研究探索虚拟化框架的安全增强技术。MARVEL
[20]引入了可信容器的概念,但未详细描述可信容器的建立方式,其主要关注插进应用与可信容器应用之间的身份验证机制,用于抵御重打包攻击。其定制过的应用无法在Android原生系统上运行,导致兼容性和可扩展性较差。
多开应用中安全问题的核心在于应用间共享UID导致Android原有的权限机制失效,而多开应用开发者为了降低成本没有在虚拟环境内部实现应用隔离。PluginPermCheck
[34]提出了细粒度的权限管控方法,但其动态介入易受攻击者绕过,保护能力相对有限。为提高应用层虚拟化框架的安全性,一些研究如Boxify通过不同应用程序进程之间的隔离构建安全虚拟化环境,但在处理应用间通信问题上存在不足
[35]。NJAS则通过生成兼容的空壳应用加载原生应用的代码和资源,虽然解决了权限继承问题,但其使用ptrace拦截系统调用可能导致进程中断和崩溃问题
[36]。因此,如何在提高虚拟化框架的安全性同时不影响兼容性,是当前研究需要攻克的技术难题。
5 结 语
Android应用层虚拟化框架在多开应用中的广泛应用引发了对其安全性的关注。自2016年以来,针对基于应用层虚拟化技术的Android多开应用的安全研究逐渐兴起。通过深入研究虚拟化框架的特性,研究者们提出了一系列静态和动态方法来识别这类环境,取得了一定的研究成果。然而,目前在多开应用的安全增强技术方面仍存在提升空间。
1) 改进虚拟环境检测方法:未来研究可集中在提升虚拟环境检测方法的对抗性,引入更复杂的机制以抵御恶意容器应用的攻击。通过综合多种静态和动态检测方式,提高对多开应用环境检测的准确性和全面性,以适应攻击的多样性。在保障安全性前提下优化用户体验,例如提供用户选择是否继续运行的选项,平衡安全性和功能可用性。为降低性能开销,研究探索更高效的实时监测方法,包括优化监测算法、减少资源占用。
2) 整合提升防御重打包攻击技术:整合MARVEL的防御重打包技术与已有的虚拟环境检测技术,实现更强大的综合防御。当检测到虚拟环境存在时,系统可自动启动MARVEL的防御机制,并在真实系统中维持普通的反篡改保护机制。这种方法不仅充分利用了MARVEL在防御重打包方面的优势,还强化了整体系统对于虚拟环境的综合应对能力,提高了系统的安全性和稳定性。
3) 安全多开应用的构建方法:构建安全多开应用可通过多方面着手,包括采用安全容器技术确保应用隔离、引入权限管理机制限制插件应用权限、设计可信验证机制确认应用完整性,以及严格控制应用通信等。未来研究可着力提高多开应用的整体安全性,包括设计更强大的安全容器技术,兼顾安全性与性能平衡;探索更细致的权限管理方法和优化应用通信保护机制,同时加强对安全漏洞和隐私泄露的检测和防范;整合多种安全技术形成全面的解决方案,确保多开应用的整体安全性。
4) 多开应用的隐私问题:鉴于多开应用通常需要额外权限,隐私风险增加。当前的隐私声明往往只涵盖了有限的数据使用情况,而在多开应用中引入的新应用可能会涉及违规隐私数据收集的问题。未来研究可着重完善隐私声明标准,要求多开应用清晰说明对敏感权限的使用方式,加强用户隐私保护。同时,探索智能权限管理和隐私监控技术,减少权限滥用和隐私泄露的风险。通过提升用户知情权,使用户更深入了解多开应用对其数据的使用方式,从而加强用户隐私意识和主动权。这些研究有望提高多开应用在隐私方面的安全性。
国家自然科学基金(62272351)