昨天傍晚盘古实验室负责任的披露了针对 iOS 应用的 ZipperDown 漏洞,并提供了检索、查询受影响应用的平台: zipperdown.com。基于目前公开的信息,该漏洞的影响面比较大,15000 多个应用可能受此漏洞影响。 并且,结合应用中的其它安全缺陷,可以在某些应用上获得远程任意代码执行能力,即:远程控制目标应用,危害也较大。由于目前官方没有公开 ZipperDown 的详细信息,所以这里会跟大家分享、探讨一下针对 iOS 应用的防守策略以及针对具体功能点的防守方法。
出发点与基本策略我们谈的主要是防守,谈防守就要基于一定的信任基础,如果什么都不可信,那也就没法做防守了。再具体一点,我们现在谈的是 iOS App 的防守,我们信任的基础是 iOS,即:iOS 系统及服务是可信的,他们的安全性是完整的,没有被破坏的。对于 iOS 应用而言,操作系统提供的最基本、最重要的安全特性是:代码签名、沙盒。代码签名是指:iOS 上只能运行由苹果签名的代码。沙盒是一种限制程序行为的安全特性,其中包括对程序可以访问的文件的限制,如:App1 无法访问 App2 存储的数据文件。除了代码签名与沙盒,iOS 上还有其它的一些安全特性或者安全功能,比如:Keychain、用户数据加密等。我们做防守时一定要充分利用现有的安全功能与安全特性,换句话说就是:充分利用苹果提供的资源,这样可以大大降低我们的防守成本,这就是第一条防守策略:尽量基于现有的防御阵地来搭建我们自己的防线。
防守的第二条策略是:要搭建防线。搭建防线,换句话说就是:没有银弹,没有什么单一的防御点可以从整体上保证我们的 App 的安全。以本地存储为例,从 iOS 8.4 之后,没法导出单个应用的存储在设备上的文件,那我们还用不用对 App 存储到本地的数据进行加密?对于我们公司的产品,我们是要求加密的,原因是:如果不加密,我们就依赖于 Bundle 不可导出这个安全特性,但是 Bundle 真的不可导出吗?!有没有办法绕过?实际上是有办法绕过的,我们还可以通过备份手机进而获得应用的数据。所以,如果做了本地数据加密,可以将这个理解为增加了一条防线,那应用就可以抵御后一种攻击方式。
防守的第三条策略是:要持续的、牢牢的抓住主要“矛盾”。对于 iOS 应用而言,我们认为主要矛盾是:远程代码执行。远程代码执行的前提是攻击者可以远程的将攻击 Payload 投放到 iOS 应用中。对于投递恶意 Payload,首先想到的方式是中间人攻击(MitM)。为了避免 MitM,我们要求 App 与服务器的通信使用 HTTPS,并且需要正确的校验证书,这问题我们一直在抓,因为控制住了 HTTPS 就可以大大的降低程序的远程攻击面。在 HTTPS 之后,我们会重点关注用户可以产生内容的 App,这样又可以将攻击面降低。
防守的第四条策略是:尽量避免因为业务功能而将安全降维。这里的典型例子就是脚本能力(或者说热补能力),前面我们提过 iOS 平台的一个重要安全特性就是代码签名,由于代码签名特性、地址随机化特性、iOS App 通信特点(由 App 通过 HTTP 的方式请求 Server 上的数据),远程的在 iOS App 上获得稳定的任意代码执行是非常困难的。而脚本能力恰恰破坏了系统中基本的、重要的代码签名安全特性,可以帮助攻击者获得稳定的远程代码执行能力,从而将 App 的防御能力降维。前面有点零散的谈了我们对 iOS App 防守的理解以及防守的一些基本策略,下面我们以具体功能点为维度谈谈如何做防守。
具体功能点的防守方法 数据库文件安全安全场景描述
移动应用程序中通常会使用 SQLite 数据库来存储应用数据,而数据库本身一般存储在沙盒文件中。尽管在 iOS 8.4 之后,已经无法访问沙盒里面的用户数据,但是在 8.4 以前的设备或者是越狱设备上,数据库文件可以轻易地通过助手类工具导出。如果数据库里面存储的数据没有进行复杂的加密处理,会是应用程序有敏感信息泄漏的风险,同时也有助于攻击者进行逆向分析。
安全加固实施建议
使用较复杂的加密加盐算法对敏感数据加密后存储。
NSUSErDefaults 安全安全场景描叙
保存用户信息和属性的一个非常普通方法就是使用 NSUserDefaults。保存在 NSUserDefaults 中的信息在应用关闭后再次打开依然存在。加之 NSUserDefaults 的使用接口非常方便,导致开发人员有可能不加以区别的把数据存放到 NSUserDefautls 中。事实上保存到 NSUserDefautls 中的数据是没有加密的,可以很轻易地从沙盒中找到。NSUserDefautls 被存储在一个以应用 Bundle ID 为名称的 Plist 文件中。
安全加固实施建议
重要的敏感数据存储在 Keychain 中。
Keychain 安全安全场景描叙