APP下载

TipTracer:基于安全提示的安卓应用通用漏洞检测框架

2019-11-15杨哲慜李明琪

计算机研究与发展 2019年11期
关键词:规约安全漏洞安卓

张 磊 杨哲慜 李明琪 杨 珉

(复旦大学软件学院 上海 201203)

随着安卓系统的流行,安卓应用正被部署到数以亿计的移动设备上,庞大的安卓应用数对恶意攻击者产生了巨大的诱惑.然而,许多安卓应用,包括一些流行的应用,都包含大量的安全漏洞[1].现有的研究成果表明,大量的软件安全漏洞都是由于开发者不正确地使用安卓代码库引起的.例如对于安卓系统的Webview[1-3]、安全通讯协议(SSL)[4-5],如果应用程序以不安全的方式使用它们,就会很容易造成应用软件的安全缺陷.因此,为消除这些软件安全漏洞,我们需要首先理解为何应用软件会不恰当地使用安卓代码库,以及如何阻止这种不安全使用.

软件开发工具包(SDK)和其他库通常附带开发人员指南,指南中说明了如何安全地使用这些工具包.这些信息被称为安全提示或安全规约.有时它们也会出现在其他地方,比如谷歌的安全提示网站和一些开发者论坛(例如Android Development Community, Android People).有研究表明,这些安全提示在应用开发中并没有被严格遵守.但是,目前仍缺乏对该问题的严重程度以及其安全隐患的充分认知.此外,应用开发者们对安全规约的内容及其有效性缺乏深入的理解,这也是影响安全规约在实践中使用效果的一个重要因素.例如人们可能会问:在热门应用中,这些安全规约是否经常出现?他们什么时候受到好评、什么时候不受欢迎?对于违规行为,谁应该负起责任,库提供者或应用程序的开发人员?我们可以做些什么来使提示更有效、更有可能在应用程序开发中使用?这些问题的答案对于安卓应用安全至关重要,因为这些安全规约中报告的问题对于恶意攻击者来说也是公开的,他们可以轻易地利用这些安全隐患来攻击那些未能提供保护的应用.

理解安全规约的现状.我们系统性地研究了安全规约在大量流行应用中的实际遵守情况.为此,我们首先从谷歌官方文档、第三方库提供者和学术文献等多个渠道收集了大量的安全规约,然后我们设计并开发了一个静态分析框架,对来自谷歌官方应用市场的13 072个流行应用以及13 072个随机应用进行了检测,以判断这些应用是否违反了安全规约.结果表明:有大约50%的被测应用未遵守安全规约,导致了诸如动态加载不可信代码、隐私泄露以及SSL证书错误验证等安全漏洞问题.

此外,本文研究了Android应用程序可能会违反安全规约的原因.我们首先总结了安全规约中的11种特征并对其进行了评估,例如安全规约描述中的关键词、安全规约出现的位置、应用中使用的库等特征.然后,我们对所选的应用程序以及3个额外的应用集合进行了进一步的分析.结果显示:安全规约的违反主要由4个原因造成:

1) 模糊的语言描述.由自然语言描述的安全规约难以描述得很准确,因此也难以被开发人员抓住重点.另外,我们还发现安全规约中使用的某些关键词容易误导其读者,因为这些关键词具有多种含义.

2) 碎片化的规约分布.安全规约分散在库文档、技术论坛、技术博客等各个地方,导致开发者难以一次性获取需要遵守的安全规约集合.我们的实验结果也表明,大部分的应用只遵守了部分安全规约.

3) 误导性的代码示例.某些库的默认设置本身就不符合其安全规约.此外,同样的问题也在库的代码示例中出现,导致应用开发者无意中因参考示例代码而违反了安全规约.

4) 缺乏强制性.第三方库提供的安全规约一般都属于建议性质,缺乏相应的强制措施使开发者必须遵守.

安全规约的自动化检测.基于安全规约已公开,以及安全规约涉及的安全漏洞对所有用户(包括恶意攻击者)公开的事实,我们认为无论应用是否涉及用户的隐私数据(比如登录凭证、信用卡号码、银行账号等),应用开发者都应该严格遵守安全规约的提示,这也需要一个有效的工具来进行自动化的安全检查.因此,我们开发了一个新的静态分析检查框架TipTracer.和已有的安全检查工具不同,TipTracer是首个对安全规约文档所描述的缺陷进行强制安全检查的工具.它使用静态程序分析技术在数据流和控制流2个方面对应用中安全规约的实施情况进行自动化的检查,同时还会将具有安全漏洞的代码作为分析报告的一部分进行输出.对来自谷歌官方应用市场的大量应用进行的实验分析表明,TipTracer能有效地识别安全规约的违反情况,而且其误报率比较低.TipTracer可被应用在Android应用生命周期的3个环节:

1) 库提供者.库提供者可以将安全规约添加进TipTracer,TipTracer进而就可以自动地对使用该库的安卓应用进行安全规约遵守情况的检查.

2) 应用开发者.应用开发者可以使用TipTracer来检查该应用是否遵守库提供者所给出的安全规约.

3) 应用市场.应用市场可以使用TipTracer来对应用进行审核,进而识别应用中是否违反应满足的安全规约.

本文的主要贡献有3个方面:

1) 系统研究了移动应用对安全规约的遵守情况.本文对安全规约的遵守情况进行了大规模系统化的研究,发现移动应用普遍忽视安全规约,导致应用程序包含大量安全漏洞.其原因主要为:安全规约通常语言表述较为模糊、规约分布比较碎片化、示例代码也会违反规约本身以及目前缺乏强制性手段帮助开发者遵守安全规约.此外,由于这些安全规约及相关漏洞报告已经被公开,应用漏洞面临着巨大的被攻击风险.同时,为了使开发者能更好的遵守安全规约,其质量也需要进一步提高.

2) 实现了一个自动化检查安全规约的程序分析框架.本文设计了首个自动化检查应用中安全规约遵守情况的检测框架TipTracer.该框架提供了一个形式化语言对安全规约进行表述,并利用程序分析技术在控制流和数据流2个角度对移动应用进行检查.同时,该框架的形式化规则语言不仅可以表述已有安全规约,也可以用于其他漏洞表述,具有通用性.

3) 大规模的实验分析.本文收集了部分安全规约,并以表述这些规约为例展示了如何利用TipTracer的漏洞检测能力.通过对谷歌官方应用市场中的大量应用进行了检测,发现超过50%的应用都存在违反安全规约的情况.

1 安全提示的选取

我们在安卓与第三方代码库所提供的安全规约中选择了七大类提示进行研究.

1.1 安卓原生代码库的安全提示

1)MODE_WORLD_READABLE相关的安全提示

安卓应用可以在使用共享配置(shared-preference)、数据库实例或本地文件时使用MODE_WORLD_READABLE模式以允许其他应用读取其本地存储空间中的内容.但是,一旦本地存储空间被以MODE_WORLD_READABLE模式进行过访问,任何将本地信息写入这一存储空间的操作都是危险的,因为带有MODE_WORLD_READABLE标志的存储空间无法对来自未授权应用的读取操作做出限制.因此,恶意应用可以在未经授权的情况下从这些文件中获取敏感信息.我们在图1中给出了一个关于MODE_WORLD_READABLE模式的安全规约示例.

类似于MODE_WORLD_READABLE向所有应用授予了应用本地存储空间的读取权限,MODE_WORLD_WRITABLE向所有应用授予了写入应用本地存储空间的权限.因此,从带有MODE_WORLD_WRITABLE的存储空间中加载和使用数据是存在安全隐患的.带有MODE_WORLD_WRITABLE标志的存储空间中的数据甚至会被未经授权的应用损坏.图1给出了一个关于MODE_WORLD_WRITABLE的安全规则示例.

此外,我们还选取了在已有工作中已经被提及的一些其他安全提示.我们选择这些安全提示主要是为了证明TipTracer作为通用漏洞检测框架的能力.具体来说,首先,我们收集了大量Google Play上的最新应用;然后,利用现有的已知工具对这些应用进行分析,并将其分析结果作为基准;最后,我们利用TipTracer来分析这些应用,并将分析结果与基准进行对比以确保TipTracer能覆盖现有工作的结果.在实际实验中,我们研究了3个安全提示:

1) SSL相关的安全提示

正如Google关于SSL的官方文档[6]中所表述的,若应用未正确的使用SSL代码库,则恶意应用就有机会在网络上截获该应用的数据.具体来说,安全提示警告开发者避免使用信任所有证书的自定义主机名验证器(hostname verifier),同时应用程序也不应该通过使用SSL-SocketFactory类来信任所有的主机名.TipTracer的安全规约覆盖了所有这些对SSL代码库的误用.

2) 与数据加密代码库相关的安全提示

CryptoLint[7]研究了Android应用对数据加密代码库的误用情况,并将其总结为6条安全建议.例如应用在加密时不应使用ECB模式,应用也不应在对数据进行CBC加密时使用非随机的初始化向量.类似的安全提示在安卓安全提示页[8]上也存在.TipTracer继承了其关于不安全使用加密代码库的定义和相关安全规约.

3) 与动态代码载入机制相关的安全提示

动态代码载入机制允许应用动态加载在程序启动前并不知晓的Java代码.由于通常会从外部存储设备上加载代码,动态代码载入会显著增加应用被恶意第三方通过代码注入或代码篡改进行攻击的可能性.通过研究安卓开发者指南[8-9]中官方的安全提示,及Poeplau等人的工作[10]中提供的安全提示信息,我们导出了使用安卓动态代码加载类的安全规约.该安全规约会驱动TipTracer检查应用是否会动态地从不安全的存储空间加载代码,以及应用是否使用了不安全的存储空间来缓存动态加载的类.

1.2 第三方代码库的安全提示

安卓原生代码库的安全提示在已有的工作中已被讨论过,TipTracer可以形式化地表述它们对应的安全规约并自动地验证应用是否满足了这些安全规约.此外,本文首次研究了第三方代码库中的安全提示.下面是本文选取的2个安全提示示例:

1) SQLCipher代码库的安全提示

SQLCipher[11]代码库是一个流行的基于SQLite数据库的第三方扩展代码库.该代码库封装了对数据库文件进行256位AES加密的功能,同时应用开发者无需考虑加密过程的细节.然而,在使用SQLCipher数据库时,不将固定的解密密钥放入应用程序客户端文件中是保证数据存储安全的一个关键因素,因为如果应用程序使用固定密钥,攻击者就可以通过从应用程序的安装包中提取密钥并对数据库进行解密操作[12-14].

2) LockPattern代码库的安全提示

Lock Pattern是一个第三方隐私保护扩展,该代码库为应用提供了添加图形化锁定模块的功能,该模块可以被用于保护应用程序内部数据不被未授权的其他用户使用.为保护图形密钥,LockPattern的安全提示要求开发者对用户设定的图形模式[15]使用自定义的加密器进行加密.若应用未设置自定义的加密类,LockPattern会使用原始的哈希函数来对图形密码进行加密,而这种加密方法可以轻易的被攻击者所攻破并解密.图2展示了从这一安全提示导出的安全规约.

1.3 违反安全规约的示例

图2给出了软件安全提示违反的一个实例:LockPatternActivity.LockPattern在其软件安全规约中指出,在启动器LockPatternActivity之前,应用软件需要首先调用setEncrypterClass方法来指定一个加密器.在图2中,有漏洞的应用在未指定加密器的情况下启动了LockPatternActivity.我们可以将这一实例通过2个函数调用事件及其时间顺序进行描述:首先,应用程序创建了一个Intent对象,并将其对应的组件类设置为LockPatternActivity(行④).之后,应用程序在调用setEncrypterClass函数(行⑥)之前启动了Intent对象指定的Activity(行⑦).

2 安全规约机制所存在的问题

2.1 安全提示缺乏强制力

应用软件安全建议通过语言这一载体,以非正式的方式传达给程序员.同时,我们发现现有工具都不能检测应用软件因违反安全建议而产生的应用安全问题.通过分析安卓应用程序编写和编译机制,我们发现在编译阶段,编译器没有对应用程序违反安全建议的行为抛出编译时错误,因此,现有安卓应用编译机制无法避免应用程序因程序员违反安全建议而造成的安全缺陷.此外,我们发现编译器只会在少数安全建议违反的情况下才发出警告,而这些警告都是因为应用程序访问了过时的系统调用接口.然而,由于使用过时系统调用接口并不代表应用程序会存在安全问题,因为这类编译时警告往往被程序员所忽略.

2.2 安全提示的碎片化现象

我们发现代码库开发者在向程序开发者传达安全建议时,并没有一个统一的传达渠道,而是通过将安全建议集成入API文档、使用实例、安全教程中或者在开发者博客和论坛上发布安全建议说明等方式传达安全建议内容.这种安全建议的碎片化现象使得开发者很难掌握其所使用的代码库完全的安全使用需求.

实例分析1. 动态代码加载安全建议.

Java语言的动态代码加载机制为应用程序提供在运行时动态加载程序代码的途径.通过这一途径,程序员可以灵活控制加载入应用的程序代码.然而,由于通过动态代码加载机制载入应用的代码将在应用程序中被直接运行,因此如果在加载过程中,访问了不安全的外部存储位置(如SD卡)或者通过未加密的通道从远程服务器加载代码库,应用程序就可能面临被恶意入侵者劫持的风险.今年年初,Poeplau等人[10]介绍了在安卓应用程序中,因为应用程序开发者不安全使用动态代码加载机制带来的软件安全漏洞.

事实上,在谷歌官方的开发者文档中,对于动态代码机制的安全问题已经提出了相应的安全建议.然而,对于对应代码库的安全建议主要有2条,而对于这2条安全建议的描述却被分散在2个不同的位置:在安卓开发者文档的“安全提示(security tips)”页[8]中,代码库设计者强调在使用动态代码加载时,开发者需要确保被加载的代码必须来自于不可被篡改的安全加载源.另外,在开发者文档中的DexClass-Loader的接口页[9]中,代码库设计者强调在使用动态代码加载时,开发者需要确保被加载的代码不可被缓存在可被篡改的介质中.被分散的安全建议造成软件开发者无法完整捕获动态代码加载的安全规约,而一旦开发者错失部分的安全建议,就可能导致应用程序存在不安全加载动态代码库的行为.

2.3 开发者对安全提示的错误理解问题

目前,安卓代码库的安全建议均采用自然语言的方式呈现给程序开发者.由于自然语言中存在复杂语义,并且可能包含大量存在歧义和具误导性的词或句子,因此应用开发者在阅读安全建议时可能会误解安全建议的内容.尤其是当程序开发者的母语和安全建议所使用语言不一致时,该问题更为严重.

实例分析2. Rastreador celular Inteligente.

安卓应用程序在使用SharedPreference,本地数据库或者本地文件存储私有数据时,可以设置该数据的共享模式.在这一过程中,如果该共享模式被设置为MODE_WORLD_READABLE或MODE_WORLD_WRITABLE时,通过该介质存储的信息就可以被本机其他应用读取或写入.在谷歌的安全建议页[8]中,代码库设计者警告:“你应该避免使用MODE_WORLD_READABLE和MODE_WORLD_WRITABLE模式,因为他们不对特定应用程序提供访问控制,同时也不对数据存储格式做出任何限制”.

Rastreador celular Inteligente[16]是一款用于朋友之间相互发送短信的软件.在对这款软件的分析过程中,我们发现,应用程序的开发者将MODE_WORLD_READABLE误认为是MODE_READ,将MODE_WORLD_WRITABLE误认为是MODE_WRITE.因此,每当该软件需要查询本地数据库时,程序开发者都将本地数据库的访问模式设置为MODE_WORLD_READABLE.类似地,当该软件需要更新数据时,程序开发者都会将数据的共享模式设置为MODE_WORLD_WRITABLE.因此,当程序需要读写它的数据库时,它同时也赋予其他所有的应用程序读取或写入其本地数据库的权限.同时,我们发现,安卓系统代码库的所有安全建议都是使用英语书写的,而我们分析的这款软件是由一个葡萄牙公司开发的,因此,我们认为这个安全漏洞很大可能是由于开发者误解安全建议的英文表述所引起的.

2.4 误导性代码示例的影响

代码库有时会通过提供示例代码来演示对其提供接口的使用方法.与之类似地,一些关于安卓开发的书籍或者在网上的技术谈论文章中,也时常通过实例代码演示对安卓代码库的使用方法.我们发现安卓应用的开发者不仅会浏览演示示例的内容,还会将其中的代码复制到自己的应用中,从而减少开发成本.然而,如果示例代码本身包含不完全的代码库使用,将示例代码嵌入应用这一行为将造成开发中应用得安全缺陷.

实例分析3. 已出版的安卓书籍.

如果应用程序使用MODE_WORLD_READABLE或者MODE_WORLD_WRITABLE这2个参数访问本地存储的数据,会造成其本地数据全局可读或可写,并代码应用程序的安全隐患.本节我们进一步研究了存在于安卓示例代码中对这2项不安全配置的使用情况.我们的观察结果显示,误导性的代码片段不仅在网上的技术文章与相关技术讨论中被大量误用,类似使用也存在于已出版的介绍安卓开发的图书中.我们发现在至少3本技术类书籍[17-19]中包含了不安全的代码库使用,并且在这些数据中都没有给出相关的安全提示.

2.5 案例研究:第三方代码库

在安卓原生代码库以外,我们还研究了2个用于增强应用安全性的第三方安卓代码库:SQLCipher与LockPattern:SQLCipher[11]提供了对应用程序本地SQLite数据库进行256位AES加密的功能,应用程序可以通过库函数接口进行加密配置,而不需要考虑加密函数的细节.LockPattern提供了给应用程序添加图形化锁定模块的功能,该模块可以被用于保护应用程序内部数据不被未授权其他用户使用.它们都含有上文中所提到的问题.

1) 我们发现这些第三方代码库在描述安全需求时,比原生安卓代码库更倾向于使用模糊或较弱的表述方式,比如他们经常使用“更加安全”或“建议使用……而非……”的方式描述安全需求.这很容易引起程序员的误解.相反,安卓开发者文档更倾向于使用较强的语气表述需求,如“避免……”或“……将引起漏洞”等.

2) 这些第三方代码库都未将安全提示放进其接口文档或代码库使用教程中.我们发现它们有时将安全提示放在了开发者博客[13]的一个单独的页面上,有时将其放在接口文档的不明显的角落切没有明显指向该页面的链接[15].更有甚者,有时代码库开发者还将安全提示散布于Google群组讨论[12]或者Stackoverflow的问答[14]中.碎片化的安全提示使开发人员难以理解代码库所提出的需求并遵守相关要求.

3) 虽然SQLCipher在其安全提示中建议不要将固定的密钥置于应用程序代码中,我们仍然发现在SQLCipher的官方代码库使用教程[20]与SQLChipherForAndroid-SDK[21]的示例中存在使用固定密钥的情况.

3 TipTracer的整体架构

为了在移动应用中大规模检测安全规约的遵守情况,我们设计并实现了一个基于静态分析的安卓应用通用漏洞检测框架,名为TipTracer.图3展示了TipTracer的总体架构.该框架主要由一个安全规约模型与一个静态软件分析器构成.

1) 安全规约模型.为了解决在2.3节中讨论的由安全提示的自然语言描述特性带来的语义误解问题,我们设计了一个编程模型来形式化地描述代码安全规约.由于安全提示普遍在方法级别描述程序的正常代码库使用行为,TipTracer的安全规约模型允许代码库设计人员描述方法调用的安全时间顺序、调用参数与返回值间的数据依赖关系,以及对参数赋予的限制.在第5节中我们将详细描述该安全规约模型.

Fig. 3 Architecture of TipTracer图3 TipTracer 的总体架构

2) 静态软件分析器.基于代码库安全规约模型在控制流和数据流上描述了应用软件应该遵守什么行为规范.因此,静态软件分析器通过对目标应用代码进行控制流与数据流分析,利用程序切片技术定位安全规约相关的应用代码,再检测这些代码是否符合行为规范.第5节中我们将对该分析器的设计细节做详细描述.

4 TipTracer的属性描述

TipTracer通过利用代码库安全规约对应用软件安全性进行检测.在TipTracer进行安全检测之前,我们需要对安全提示所提出的代码库安全使用需求进行形式化描述.在本节中,我们首先给出了TipTracer所支持的安全规约类型,然后对安全规约逻辑进行了形式化的定义.

4.1 属性类型

软件安全提示通常在函数粒度指导开发者如何使用库API,包括各个函数调用之间的先后关系或调用特定函数时需要满足的参数数据限制.TipTracer中定义的软件安全规约描述了违背这些代码库使用约束的情形.

1) 不安全接口调用顺序.该情形限制了函数接口之间调用顺序应该满足特定先后关系.比如通常情况下,在用HTTP接口传播密码之前,都应该先调用对应的加密函数,以防止可能的密码泄露.

2) 不安全的数据传播.该情形限制了函数的参数所需满足的数据污染关系.比如很多库都规定对用户隐私数据的使用应当小心谨慎,不应该流入log日志中等可能被攻击者访问到的数据节点上.

3) 不安全参数值.该情形限制了函数接口所能接受的参数应该满足的限制条件.比如很多库规定开发者应该使用有效的加密方法对敏感数据进行保护,但是如果在使用加密函数Cipher.getInstance()时设定第2个参数为“ECB”,将导致该软件使用弱加密,即使用了不安全的参数值.

4.2 基本元素

在定义TipTracer安全规约之前,我们首先定义用于组成安全规约的基本元素:执行点和数据点.

1) 执行点(execution point, EP)

执行点代表对一个函数的具体调用点.一般情况下,每个函数都具有独立且唯一的方法签名(signature),因此,我们使用方法签名去表示每一个函数调用点,即执行点.例如在安卓系统中可以用EP(“android.content.Context.getSharedPreferences”)表示一个调用getSharedPreferences这个方法的执行点.此外,我们也定义了2个特殊的程序执行点:ProgramEntry和ProgramExit,用于表示整个应用程序执行时的入口和出口.我们也定义了用于对某一函数的所有调用点的集合表示方法EPS.如EPS(“android.content.Context.getSharedPreferences”)可以表示在应用软件运行时所有对getSharedPreferences方法的调用点.

2) 数据点(data point, DP)

数据点代表程序执行中出现的所有数据节点,包括所有方法调用的参数、返回值以及所有的全局变量.类似于执行点集合(EPS),数据点集合(DPS)也被定义为所有同类数据点的集合.

4.3 规则逻辑

TipTracer的规则系统支持逻辑组合.使用上面定义的基本元素,再结合一些逻辑组合关系,可以定义出各种各样的复杂安全规则.具体而言,本系统中支持3种规则逻辑.

4.3.1 时序规则

为了表示指令之间的先后顺序关系,一种可能的方法是使用状态机[22-23].但是,许多安全规则在限定函数执行顺序的同时也对其参数进行规范,使用状态机时并不容易表示.因此,本文定义了一个新的三元组用以表示时序规则,具体是:

Rule∷Temporal(EPSS,EPS1,EPSE,mode),

其中,EPSS为起始执行点集合,EPS1为中间执行点集合,EPSE为结束执行点集合.mode包含2种模式PROP_SKIP或PROP_PASS_THROUGH.如果mode为PROP_PASS_THROUGH,则表示如果在应用软件从EPSS执行到EPSE的过程中,如果存在一条执行路径包含了EPS1的执行点,则存在安全隐患;如果mode为PROP_SKIP,则表示如果在应用软件从EPSS执行到EPSE的过程中,如果任意一条执行路径都不包含EPS1的执行点,则存在安全隐患.例如,图8中的规则r3表示在目标Activity启动之前,应用程序应首先调用方法setEncrypterClass.

4.3.2 数据传播规则

数据传播规则主要用来限定应用软件中的敏感数据流,具体表述是:

Rule∷Propagation(DPSS,DPSE,mode),

其中,DPSS表示数据传播过程中的起始数据点,DPSE表示数据传播过程中的结束数据点,mode同样包含2种模式PROP_MAY和PROP_MAYNOT.如果mode为PROP_MAY,则表示在应用程序执行的过程中,如果存在数据从数据点集合DPSS流向数据点集合DPSE时,则存在安全隐患.例如图4中的规则表示,如果应用软件将外部数据传入到敏感数据点(DexClassLoader的第2个参数),则存在安全隐患.

如果mode为PROP_MAYNOT,则如果应用软件执行时,对于结束数据点集合DPSE,如果不存在数据从数据点集合DPSS流入时,则存在安全隐患.例如,图5中的规则表示,在设置SQLCipher数据库加密密钥参数的路径时,如果没有将其设置为来自于外部数据源,则说明应用软件存在安全隐患.

4.3.3 参数赋值规则

参数赋值规则用于表示函数调用时参数值应该满足的限制条件,具体为

Rule∷Assignment(DPS,ViolationPattern).

与另外2种规则不同,该规则只用来对单个数据点进行限定,包括函数的参数、返回值以及全局变量等.ViolationPattern用来表示对数据点附加的具体限制,如数值的合法取值范围、字符串应当满足的正则表达式特征等.同时,我们也定义了一些特殊变量的关键字,比如关键字CONST可以用来表示所有常数类型的参数.例如图6中给出的规则限定了在使用加密算法时不能使用ECB模式.

在4.3.1~4.3.3节中,我们描述了TipTracer使用的3种基本安全规约类型.但是,很多复杂的安全规约并不能简单地利用一种规则进行描述.因此,TipTracer提供了逻辑操作(逻辑与、逻辑或、逻辑非)来合并多个安全规则以组成复杂规则.例如图7中的行⑨展示了逻辑与的一个具体实例,它表示只有应用程序同时违反这几个安全规则时才会被认定为违反安全规约.

为了配合多个安全规则之间的逻辑操作,TipTracer额外提供了一个绑定(bind)功能,以方便将执行点与对应的数据点结合在一起.例如在图7中,通过绑定功能,2个安全规则r1和r2共同完成了应用程序不能将数据库设定为全局可读写模式的安全规约:规则r1使用参数赋值规则限定了openOrCreateDatabase的第3个参数为2(MODE_WORLD_WRITABLE)或3(MODE_WORLD_READABLE|MODE_WORLD_WRITABLE),而规则r2限定了应用程序打开数据库的行为.这2个安全规则之间是存在数据依赖的,因为它们同时是针对同一数据库对象进行限定.因此,我们需要将数据点集合dps1与dps2绑定到执行点ep1上,以表示它们代表着同一个数据库对象,即这2个数据点对应同一个执行点.

图8给出了LockPatternActivity相关的软件安全规约.在该安全规约中,我们使用了3个基本安全规约来描述对应的安全提示违反需要满足的3个关键点:首先,应用程序将组件类LockPattern-Activity传递到一个Intent对象的构造函数中(属性r1).随后,应用程序将Intent对象传播到Activity的初始化方法中(属性r2).最后,在启动新的Activity之前应用程序未调用setEncrypterClass方法(属性r3).此外,r1中创建的Intent对象应该与传递到r2中的Intent对象相同,所以r1与r2应共享同样的Intent对象创建指令.因此,我们将属于共享方法调用的数据点集合dps1与dps2绑定到同样的执行点ep1上.类似地,r2与r3共享同样的Activity启动指令,因此我们同样将startActivity方法调用的2个数据点dps3和dps4都与执行点ep2进行绑定.

为了理解这一软件安全规约的作用原理,我们将图2中含有漏洞的应用程序与图8中建立的安全规约进行匹配:

1) 指令4满足r1中定义的参数赋值规则.

2) 应用程序将指令4中创建的Intent对象传递到指令7中,这符合r2中定义的数据传播规则.

3) 应用程序在调用setEncrypterClass之前在指令7中调用了startActivity方法,因此r3被满足.

4)r1与r2共享同样的执行点(指令4),但r2与r3共享另一执行点(指令7),因此安全规约的绑定约束也与启发示例中的代码相符.

5) 因此,图2符合图8中的所有描述,其违反了图8建立的安全规约.

Fig. 8 An example of violation of rule LockPatternActivity
图8 LockPatternActivity的安全规约示例

5 TipTracer的实现与评测

5.1 TipTracer的实现

TipTracer实现在Soot静态分析框架[24]的基础上,支持安卓APK文件、安卓应用源代码以及安卓应用字节码等多种输入形式.在4.3节中,我们提出了TipTracer支持的安全规约系统,主要包含3种安全规约.因为通过相互组合,这3种安全规则可以描述各种复杂情况,包括但不限于已知的安卓安全规约,因此,TipTracer可做为通用漏洞检测框架进一步扩展,只需将漏洞特征以安全规则的形式进行书写.本文仅是以安全规约这一应用场景为例,展示TipTracer的漏洞检测能力.

在TipTracer系统中,针对这3种基本安全规则限定的条件,我们采用不同的方法进行分析.首先,对于时序规则,因其表述的是相关函数调用指令的执行顺序,我们利用代码可达性分析[25]技术在程序控制流图上检测代码执行顺序是否满足规则约束.其次,针对数据传播规则,我们首先结合了一个静态污点分析工具FlowDroid[26],利用其污点分析能力构建出程序数据流图,再检测数据污染关系是否满足安全规则限定.此外,对于常量,我们利用常量传播分析[27]来分析其传播过程是否符合安全规则.

因为TipTracer支持安全规则之间的相互绑定关系,我们会在每一轮分析的结尾部分,对剩余分析对象是否还满足绑定关系进行判断,以消减进行下一轮分析的代码数量,进一步加快整个程序分析进程.同时,在每一轮分析中,为了避免对整个应用程序代码做多余分析,我们利用程序切片技术仅抽取目标数据点、执行点附近的代码用于分析.具体来说,我们用后向数据流分析确定程序切片的起点,再利用正向数据流分析确定其终点.然后利用控制流图补全程序切片里的指令.

TipTracer使用了3种不同静态分析方法来验证4.3节提到的3种基本安全规约.首先,TipTracer使用的每种静态分析方法都与其他几种分析方法相互独立,即不论TipTracer以何种顺序进行静态分析都不会影响到其对应用进行规约验证的结果.然而,运行不同程序分析的顺序将极大地影响到TipTracer进行规约验证的效率.我们观察到,静态分析在检查数据传播规则时其分析速度会比检查时序规则与参数赋值规则慢.此外,常量传播分析的速度相对稳定,受其他条件影响比较小.因此,TipTracer采用调度策略去调整这几种分析技术的先后顺序以加快整体分析的速度.具体来说,TipTracer首先检测参数赋值规则,其次时序规则.而速度最慢的数据传播规则被留到了最后.这样经过每一轮分析结尾阶段对待测目标的消减,在数据传播分析阶段仅剩下较少代码片段,可大幅提升整体分析速度.

5.2 TipTracer测试结果

5.2.1 TipTracer发现的应用软件安全漏洞

首先,我们使用于2015年11月从Google Play上获取的2批应用软件作为测试集,以此对TipTracer发现应用软件安全漏洞的能力做出评估.其中,第1批13 072个应用包含了在Google Play上每一分类中最流行的500个应用,第2批应用包含了13 072个从Google Play上随机选取的应用.图9展示了2批应用中违反代码库安全提示的应用数分布.根据我们的测试结果,大约52%的流行免费应用与38%的随机选取的应用存在安全漏洞.为验证TipTracer的结果,我们从每个安全规约类别中随机选择有漏洞的应用程序进行人工验证.在被检查的411个应用中,有9个应用的安全漏洞是TipTracer的误报,这意味着TipTracer的假阳率为2.1%.根据我们的进一步分析,所有的假阳性结果都是在验证数据传播规则时发生的(该规则使用了静态污点分析方法进行验证).由于上下文敏感或域敏感的数据流分析过程非常耗时,所以我们采用的污点分析算法使用了上下文不敏感且域不敏感的分析方法以节省分析时间.但是,这种方法是不精确的.根据我们的验证结果,在这些由TipTracer得出的假阳性结果中,有6个是由于TipTracer在静态污点分析时使用不精确但省时的方法引起的.这些误报可以通过使用上下文敏感、域敏感的方法来加以消除.其余3个假阳性结果是由FlowDroid中的错误引起的.

Fig. 9 Distribution of violated apps from Google Play图9 Google Play上违反安全提示的应用数分布

为进一步了解存在安全漏洞应用的分布情况,图10统计了各下载量区段应用中违反安全提示的应用分布.对于不同的用户下载量,图10给出了随机选取的应用中违反安全提示应用的比例.从图10可以看出,有漏洞应用比例在不同的下载量区间中相对稳定,而在下载量比较大的应用中稍微较多.因此,不论是流行应用还是排名靠后的应用都存在违反安全提示的情况.

Fig. 10 The download numbers of violated apps图10 违背安全提示的应用下载量分布

5.2.2 安全漏洞的持续存在性

为了评估软件中安全漏洞随时间的变化情况,我们选择了另外两批安卓应用作为样本.其中一批样本包含10 000个在2012年从Google Play上随机选择的应用;另一批包含在2014年获取的同样的应用.在这部分测试中,因为在2012年没有使用我们测试的第三方代码库LockPattern,因此我们没有测试这些应用中第三方代码库LockPattern所包含的安全提示.表1显示:在2012年违反安全规约的1 753个有漏洞的应用中仅363个在2014年修复了应用中的安全漏洞.该结果显示安全提示对消除安全漏洞仅起到了很小的作用.

Table 1 Violation of Security Tips in Goolge Play Appsand the Fix

5.2.3 概念验证攻击

本文不仅研究了在已有研究中被提及的安全提示信息,也对许多在本文中首次被提及的安全提示进行了研究.在本节中,我们通过对真实应用进行实际攻击来展示本文提到的安全漏洞如何使得应用程序容易受攻击者攻击.

1) 解密SQLCipher数据库

与安卓系统原生的数据库解决方案不同,SQLCipher代码库提供了对数据库文件进行256位AES加密的功能,同时应用程序无需考虑加密的细节.应用程序开发者通常会将SQLCipher当作安全的数据库加密方案,并认为其他应用是无法解密SQLCipher数据库中的内容的.因此,开发者也会认为,存储在SQLCipher数据库中的内容不会被恶意应用访问,并在设备丢失或被盗的情况下也是安全的.但是,利用本文中发现的安全漏洞,我们可以通过采用3个步骤来对SQLCipher数据库文件进行解密:

① 利用TipTracer分析目标应用,TipTracer会指出应用软件不安全的创建SQLCipher数据库的相关代码.

② 需要在SQLCipher创建数据库代码前插桩代码,该代码提取用于创建数据库的密钥,并将密钥写入日志中.

③ 利用该密钥,可以编写一个应用来对SQLCipher数据库进行解密.由于数据库密钥是被嵌入到应用中的一个固定密钥,因此编写的应用可以在理论上解密目标应用的任何数据库实例.

我们研究了由TipTracer报告的10款应用.在我们的示例攻击中,我们成功解密了所有被报告应用的数据库.

2) 获取应用本地文件

由于受到安卓沙箱机制的保护,应用程序开发者通常会假设应用的本地文件不会被其他应用软件访问.而正如3.3节的描述,TipTracer找到了一系列通过MODE_WORLD_READABLE模式访问自身本地存储的应用.由于MODE_WORLD_READABLE模式无法对存储空间的访问者做出限制,这些应用的存诸空间有可能会被恶意应用所窃取.为不失一般性,我们从TipTracer的报告中随机选择了10个应用,并编写了与之安全漏洞相对应的示例攻击应用.我们确认示例攻击应用可以在未获取任何安卓权限的情况下获取这些应用本地文件中的内容.

5.2.4 本文其他发现

1) 流行的免费应用并未能更好地遵守代码库安全提示

我们可能会认为流行的免费应用会更少地违反安全提示,因为它们的开发者有更多的资源来提升应用的质量.但是,表2显示流行应用所违反的安全提示数量甚至超过了随机选择应用所违反的数量.我们的人工验证表明,流行免费应用更趋向于使用安全敏感的代码库,但它们的开发者通常会忽略代码库所提出的安全需求与安全提示.同时,排名靠后的应用常会使用完全没有安全保证的代码库,而使用这样的代码库会对应用的安全造成极大的威胁.

Table 2 Violation of Security Tips in Popular Apps and Random Apps from Google Play表2 在流行应用和随机应用中对安全提示的违反情况

2) 第三方代码库的安全提示更易被应用软件开发者忽略

表2显示超过94%的使用第三方代码库(SQLCipher和LocakPattern)的应用开发者都未能遵守代码库的安全提示,对第三方代码库安全提示的违反比例远超安卓内置代码库安全提示的违规比例.在2.5节中,我们研究了这2类安全提示并讨论了这2类代码库所存在的问题.

5.3 TipTracer的分析耗时

在我们的5.2节测试过程中,TipTracer分析框架的运行环境为:

1) 双路Xeon 8核2.0 GHz CPU;

2) 32 GB内存;

3) Debian Linux,内核版本2.6.32.

我们对所有51 650个应用的静态分析过程共耗时634 h.若将分析过程的工作负载分配到多台计算机上,分析时间还可以被进一步缩短.平均每个应用的分析耗时为44 s,这一耗时对于安卓市场的运营者来说是可以忽略不计的.

6 关于TipTracer的讨论

TipTracer是一个对给定的安全规约进行自动化验证的分析框架.由于代码库安全提示大多指定API层的安全实现需求,因此当前TipTracer的安全规则逻辑被设计为仅能对应用代码在方法粒度的规约做出安全约束.TipTracer尚不能在更细粒度上表述安全规约,例如TipTracer无法为一个给定方法的实现细节作出安全约束.因此,虽然目前我们发现的所有安全提示都在方法这一级别为开发者提出代码编写指导,但若要进行进一步的研究,我们仍然需要更细粒度的安全规约定义与应用分析器,细粒度的形式化定义与自动化分析是本研究未来可能的一个扩展方向.

为了消除应用程序中的不安全应用代码实现,最佳的办法是通过发出编译时错误来阻止不安全的代码实践通过编译,并防止不安全的应用被上传到应用市场.由于我们的静态分析可能会带来误报,因此有时一个安全的应用也会被误报为不安全的.幸运的是,通过记录应用违反的安全规则,以及相应的执行点集合、数据点集合,TipTracer分析器可以报告出所有违规的细节.例如TipTracer会报告每个执行点集合、数据点集合所对应的代码行,并报告数据传播规则所对应的完整传播路径,这些细节可以为开发者进行手工验证提供极大的帮助.为消除TipTracer的分析误报,一个可能的方案是使用更高精度的分析方法.例如,我们可以使用上下文敏感、字段敏感的污点分析方法来消除大部分误报.此外,大多数误报还可以通过稍微修改应用代码加以避免.例如,使用简单的数据结构来处理敏感数据(如数据库密钥),这样可以避免由字段不敏感的分析所引起的误报.

TipTracer目前与安卓应用编译器是相互独立的,我们需要先使用安卓应用编译器来生成字节码,再使用TipTracer来分析字节码.然而,某些源代码所包含的信息,如方法名等,在混淆后的字节码中会丢失,所以字节码所包含的信息量较源代码会少很多.因此,TipTracer分析混淆后的代码可能会产生遗漏.将来我们准备将TipTracer整合到安卓应用编译器中,这样可以在很大程度上减少由信息丢失带来的漏报.

7 相关工作比较

本节我们将与相关工作进行比较.

1) 安卓中的静态分析

本文我们使用程序静态分析技术检测安卓应用软件是否遵守安全规约.静态分析已经广泛用于安卓中的漏洞检测[27-31].其中静态污点分析是最流行的技术之一,它可以监控安卓系统和应用之间的数据传播[26,32-36].此技术回答了什么数据(数据源)流向了什么地方(目的地)的问题.而这也是本文工具设计的一个重要思想.但与前人工作不同的是,本文在使用该技术之前,首先对安全规约进行了形式化建模分析,并将其与静态分析技术结合起来,弥补了文本化的安全规约与程序化的静态分析之间的差距,并基于此实现了自动化的漏洞挖掘.

2) 安卓应用的漏洞挖掘

据我们所知,TipTracer是第1个系统化的研究安卓安全规约机制与对应漏洞挖掘技术的工作,并揭示了应用安全漏洞与安全规约之间的关系.目前为止,其他关于安卓应用漏洞的研究一般都只针对一种特定代码库的安全规约.例如MalloDroid[37]及Georgiev等人的工作[38]研究了网络安全通讯协议(SSL)在安卓应用软件中的使用情况.其研究结果表明,安卓应用经常误用SSL协议导致网络流量数据暴露在攻击者威胁之下;Poeplau等人[10]专门研究了安卓的动态代码加载机制,并揭示了安卓应用程序因为利用不安全的外部通道加载代码而造成安全漏洞问题;CryptoLint[7]揭示了安卓应用误用数据加密代码库所引起的安全漏洞.相对于这些研究,本文不仅系统化地研究了大量安全规约,还研究了4类之前未被研究过的软件安全规约.而且,本文提出了一整套自动化分析框架,用于检测安卓应用程序师父遵守安全规约.在该框架中,我们提出了一套安全规约语言,该语言形式化地定义了由安全提示所隐含的编程规约.相较于TipTracer可以形式化地定义和验证不同的安全规约,现有的工作目前仅完成了对特定规约的形式化定义.MC扩展[39]将安全规约以状态机的方式进行了建模,关注于对调用顺序规则的验证;MECA[40]使用基于静态污点传播的数据依赖规则.上述安全规约定义方法仅能单一地关注于纯控制流规则或纯数据流规则.而安卓代码库的安全提示所导出的安全规约可能会非常复杂,一个单一的规约可能会同时引入调用顺序规则与数据依赖规则.由于已有的规约系统不能表示复合规则,因此无法对实际需要的安全提示进行完整而准确地描述.例如有限状态自动机不能表示数据依赖规则,污点传播规则不能表示调用顺序规则.

8 结 论

本文研究了大多数代码库设计人员避免应用安全漏洞的方法,即使用安全提示来引导应用开发者编写安全的应用.与以往仅关注于某一特定类型的安全规约的研究不同,我们指出系统的理解安全提示机制的有效性与缺陷可以帮助我们识别安全漏洞的根源.此外,正如本文中所提到的那样,我们通过跟踪以往未被深入研究的安全提示,发现了许多未被报告的应用安全漏洞.基于我们对有漏洞的安卓应用与安全提示的观察,我们认为缺少自动化的验证与提示工具是许多安全漏洞产生的重要原因.因此,我们提出了TipTracer,一个新的应用分析框架来高效、自动化地验证与报告安卓应用对安全规约的遵守情况.TipTracer使用形式化的安全规约替代了以自然语言表述的安全提示,并使用了一个集中式的分析器来检测应用对安全规约的违背情况.在TipTracer分析器的帮助下,我们可以将编译时安全检查整合到安全漏洞敏感的应用市场审查过程中,提升应用市场中各类应用的安全性.

猜你喜欢

规约安全漏洞安卓
iPhone不卡的秘密曝光:安卓也能享受
传统自然资源保护规约的民俗控制机制及其现实意义
刍议计算机软件中的安全漏洞检测技术
文物表情包
安卓系统或成智能汽车标配
智能设备安全漏洞知多少
一种在复杂环境中支持容错的高性能规约框架
无人值班变电站保护信号复归方式的改进
医学留学生汉语教学“规约—开放”任务教学模式探讨
计算机软件安全漏洞检测技术