前段有关区块链智能合约的审计比较火,很多人跟着搞,本议题讲的也是安全审计,不过针对的是 iOS App,套路都可以相互借鉴,对安全研究者来说,“深度学习+迁移学习”显得尤为关键。iOS 平台上的安全问题不是一天两天的事了,远的有 XcodeGhost,近一点的则有 ZipperDown,果粉们曾引以为豪的安全性在时光的车轮中也终不复。且随着 iOS 功能不断丰富完善,例如苹果在 VR/AR 领域的布局,都使得系统攻击面相应增大,此外很大概率上还存在一些已被利用的安全问题未为人知晓。因而如何保障系统中所运行 App 的安全就成了亟需解决的难题,以下内容是由盘古实验室黄涛为我们带来的 iOS App 安全审计方面的分享,相信各位都能从中得到启发。
—— 看雪『Pwn』版主 BDomne
黄涛,看雪ID:dirge,3年软件开发经验,4年信息安全从业经验。不仅拥有丰富的开发经验,还擅长MacOS/iOS漏洞挖掘、分析,逆向工程,iOS App安全审计。曾在看雪论坛及个人站点发表大量技术文章。在macOS/iOS的漏洞研究积累了大量的经验,目前在盘古实验室从事macOS、iOS漏洞挖掘、分析与iOS App应用审计工作。
我是盘古实验室的黄涛!今天给大家分享的主题是关于“iOS APP安全审计与案例分享”
这是我的看雪ID dirge,之前做了3、4年开发,后来转过来做移动安全,主要在实验室里负责做漏洞挖掘及分析。我对开发者的想法和开发者在产品中做出的不符合规则的行为是比较熟悉的。
为什么要进行 iOS APP审计?
在2015年9月份时在App Store很多APP被注入第三方恶意代码,针对这个问题,盘古实验室紧急开发了病毒检测工具,并检测到大量的受感染的样本。这个事件大家比较熟悉,我不多做描述,有兴趣可以去自己搜索一下。
我们通过这个问题考虑为什么进行iOS APP审计?使用iOS的大部分用户或者在传统媒体只做应用开发的人认为,使用一个手机从AppStore下载一个应用是绝对安全的。事实上并不是这样的,除了ZipperDown之外还有一些问题没有被共享出来。有些APP还会收集大家的隐私和通讯录等等,所以App Store下载的应用并不完全是安全的。
大部分iOS开发人员,认为安全相关的内容与自己无关,依赖却并不是完全了解苹果的安全机制,这是在开发中很常见的,因为赶进度或者产品经理奇怪的需求,开发人员会有意无意破坏苹果提供的安全机制,导致他开发出来的APP并不安全。
根据一些报道,iOS平台恶意软件增速已经超过了安卓。
iOS平台审计更依赖于经验,安卓有很多自动化审计工具,审计安卓APP时大家会使用自动化使用工具做出一个报表,然后看看有什么需要人工去分析的地方再去深入分析。iOS不一样,市面上用的自动化审计工具非常简单,审计出来的报告没什么意义。做iOS的APP审计时需要做人工审计,更多工作内容放在人工,人工审计非常依赖经验。
iOS平台审计的工具有很多,每个都有自己特定的作用。我做了一张图,上面列出了iOS审计用到哪些工具。非常理解审计基本结构,首先,拿到一个APP需要先做静态分析,之后根据静态分析出来的结果做一些简单的动态分析,动态分析主要就是抓包,看看有没有什么危险的包,这是明显一眼可以看出来的问题。其次,根据审计出来的结果和静态分析的代码,看看比较容易出问题的代码是否用到。大家去市面找到iOS教程或书籍,可以详细的大家告诉有哪些静态工具、动态工具。我在右边列出来的的目的是告诉大家,右边所有这些工具都是有用的,但是它们没有被整合在一起、很零散,做iOS立项或者审计时需要大量时间熟悉我们用的工具。
这里是给大家总结一下我们做这么长时间iOS APP审计的常见问题:
1、不安全的随机函数。
2、APP切换到后台泄露敏感信息,比如你的手机APP在跟别人聊天,你按home会切到后台,它有一个截屏。当然,如果不是越狱的手机,基本是没有风险的。
3、存在本地数据库的SQL注入。
4、自动使用第三方键盘输入敏感信息,第三方键盘上传东西的话,可能敏感信息会被上传到服务器。
5、没有正确的使用SSL。
6、未能正确的处理所有的urlscheme接口没有详细过滤。
7、其他问题。这些都是常见的小问题,一般这种问题在开发者或者在厂商看来都不是什么大问题。
接下来看看一般厂商比较重视的问题:
1、短信验证未作限制。登陆或注册时未对获取短信验证码的次数作限制或限制不够严谨。这个问题的审计方法是通过抓包,去请求验证码的请求包,看看这个验证码会不会重新放回来。做得最差的是没有任何前置,可以向服务器请求,服务器可能会发几十条几百回,有的服务器会做一天十条或者一天二十条,或者一段时间内频繁发,它会把你阻塞,过一段时间再让你发。开发者在做检测这时一定要要严谨,我遇到一个做了检测,他根据cookie和一堆乱七八糟的ID做检测,我们通过抓包之后把所有的ID都删了,它又可以通过了,它的服务器代码分支里没有考虑到所有的词都没有情况下,所以没有做限制。最主要的问题是直接的经济损失,一条短信几分钱也是钱,一天可以发很多条。
2、非HTTPS网络请求。在访问资源没有通过HTTPS做网络请求,审计方法是打开APP通过撞户软件去看是不是有不是http的请求。这个审计方法也非常简单,就打开APP通过帐号,去看是否有不是http的请求是不是在获取敏感信息,比如拉出资源包或者txt脚本。我见过最夸张的是整个APP里面全部是http的网站,它里面包括支付、登陆,所有东西全在http里,这是非常容易损失的。这里多提一句,我们审计国外APP时,在美国的AppStore上也审计了很多APP,这个问题从来没被发现过,但国内的APP中这个问题一抓一大把,所以国内在https的使用上需要加强。传一些大的文件,CDN太贵,可以通过https传一个哈希,变通的方法,因为这个确实影响很大,在恶意的网络环境中资源文件会被替换,主要攻击就是从这里来做的,这是主要的入口。
3、敏感信息本地保存。敏感的信息例如帐号、密码或者加密使用的密钥保存在本地。这个审计方法是通过静态分析,看看有没有敏感的。它的影响是不越狱的手机是不影响的,但是你把用户的信息存在本地,如果手机丢了或者别人拿到你手机帮你越狱了,或者你的手机被别人打得越狱了,我就知道你APP里面存在的敏感信息是什么,这是其一。其二,密钥会保存在本地,APP厂商的用户有几十万,它的密钥都是这个,我自己越狱装一个APP,把这个密钥提取出来,在非越狱的手机上通过http传输的数据是通过密钥加密的,同样又可以回到内容去替换它的资源。
4、服务器信任客户端的请求。这个问题比较常见,就是服务器客户端请求中的数,最常见的就是在做一款游戏时,客户端发过来的请求服务器没有做验证,服务器直接信任客户端。《吃鸡》这种游戏是没有办法的,但同时一些卡牌手游也会有这种问题,比如游戏功能完全信赖客户端,客户端告诉它“我的服务器是完全信任的”,这样导致厂商的损失。我遇到过审计国外的APP,它把信任本地保存的图片同步到服务器上,而这张图片是做面部识别的,只要我拿到别人的手机,把它越狱,这个APP再次打开时会把我修改过的照片上传到服务器。数据库里的照片就被换成了我的照片,我拿那个APP照我的脸就可以登陆别人的帐号,这个影响比较大。这个排查起来比较简单,主要是通过源码的开发软件,检查一下客户端发出来的请求,服务器是不是完全默认。这个问题虽然很简单,但影响很大。这些都是传统的审计方法和得到的结果。
寻找新的审计方向
结合我们做自动挖掘时的经验,最常见的一种做法是通过总结程序员的习惯,就是这段代码为什么这么写。最常见的是贴代码,如果大家对iOS越狱关心的话,根据ian beer的猜测iOS10.2的越狱内存里面的一个洞就是因为贴代码造成的,程序员把另外一个代码贴到了一个新的系统调用里做修改,他把一个指针当作size。程序员贴代码是非常可怕的,做开发的都知道github最容易贴代码。
我们看审计APP里面有没有一些github的库,贴代码或者引用开源库最经常遇到的问题是什么?就是不完全理解这个开源库是干什么用的。这个开源库提供了10个功能,我只要其中的1个功能,这时把这个开源库引入我的APP库之后,这1个功能确实能够实现,但其他9个功能很有可能会影响了APP的安全。大量APP会解压Zip包,我们看这个内部到底是用什么东西解压的,发现不同厂商在解压zip包时采用的代码用的函数是一样的,很神奇,后来发现是github开源的库。
Unzip路径穿越
Unzip路径穿越的问题是什么?在附件下载、资源更新或者文件传输过程中传过来的这个包如果是一个恶意包的话,就有可能通过路径穿越的问题把沙盒文件内的覆盖掉。这是SSZipArchive被大量的APP使用。包括一些的衍生的私有的Zip库。
开源库存在问题,红框框起来的这个最后写文件的路径是通过字符串拼接得来的。构建一个恶意的zip文件,打开就可以看到“../”,做文件解压时看到这个拼成一个新的路径,通过这个图可以看到我在做一个目录之后,解压资源时把它释放出来了。
路径穿越不是一个新问题,这是一个老问题,大家如果关心安全就都了解这不是重点。重点是什么?我发现在APP里也存在路径穿越这个问题之后,我们怎么样去审计它,怎样构造可以攻击它的场景。最常见的是“路径穿越+资源替换=沙盒内任意文件覆盖”,可以去覆盖iOS沙盒内的任意文件,因为有沙盒的保护,所以不能穿到外面去。可能出现的场景是unzip+主题下载、unzip+资源更新、unzip+hotpatch。Hotpatch就是在产品需求或者产品经理需求下,程序员有意无意破坏安全模型,hotpatch一个常见,苹果很严格的把这个事情封掉了,但国际审计下来有大量的APP在使用hotpatch。这个时候如果我替换了主题、替换了资源、替换了hotpatch,都会造成不同的影响。该问题并非只出现在iOS平台下,Google的gmail在安卓下的APP也同样拥有这样的问题。
究竟AppStore里有多少APP受影响?
发现这个问题之后,我们在思考究竟AppStore里受影响的APP有多少呢?我们大量的扫描,通过静态的字符串,多少APP用了这个,然后去AppStore把这个APP下载下来,然后打开这个APP抓包,发现它有http的包,我把这个就一换,里面的文件被覆盖掉了,就抓到一个。这个事情做到最后,看到APP里面80%都有这个问题。
这个时候尝试构造一个实际的攻击情景,因为我们经过前面那么多分析,最后要把这个东西展现给大家,需要一个实际的演示。我们分析可能存在的场景有两种,第一种是APP直接接收不可信的zip文件,并使用结压,常见的是在电脑上QQ聊天时,你传给我一个文件,我把内部文件解压掉,然后干扰。第二种是通过http下载zip包,它通过解压时出现路径穿越的问题。
第一种情况思考,iOS不像安卓有文件管理器,它是看不见文件存在哪的,即便通过QQ传一个Zip包给你,不可能在手机里把它解压出来,一般都是拿到电脑里。所以我们选择iOS常见的第二种场景确定了目标,大量的APP中都存在皮肤资源或者其他图片资源的zip包,利用起来效果有限。我们简单尝试,皮肤资源或者图片资源利用之后,最多是替换一些沙盒里的文件,文件里面有可能存了一个广告或者图片,打开是一个广告,点了之后可能是引导你下载一个新的APP我把这个替换掉,可以引导他去AppSotre里下载我们自己的APP,这个使用起来效果非常有限。
在微博中我发现了hotpathc.zip的网络,而且它是通过http传递的,我们发现hotpathch有可能是js脚本去做热更新的。如果我控制了hotpathch的js脚本就可以做代码执行。通过一个恶意的WiFi热点导致用户下载的zip包被替换,完成了攻击行为。
在做这个分析过程中发现了一些问题,第一个问题,hotpatch.zip包被加密了,解决方法很简单,通过逆向看它解压时用的密码是什么就行了,这时可以看到它的密钥是保存在本地的,密钥是劫持在代码里的。第二个问题,hotpatch.zip在解压时存在签名验证,在替换了hotfix_text.js之后,在解压缩之前程序会对zip包进行签名校验,校验失败的话将不会进行zip包解压,直接删除异常的zip包。这个我折腾了一段时间,发现没办法绕过它的签名代码,这时进行了进一步思想,通过逆向分析得到两个分支,就是签名只会在zip包解压时做一次签名验证,但是如果我的hotpatch成功了,从开发者角度来说hotpatch的目的是为了修bug,我的目的是每次打开APP时,很可能js文件被解压后放在沙盒目录里的某个地方,我只要把那个文件覆盖掉,正常把它解压出来,通过另外一个方法把js文件覆盖掉,我可能就可以获得代码执行。
最终实现攻击的流程是这样的,在APP使用时,先让hotfix逻辑正常,不去替换hofix,让它的逻辑正常走,正常走完之后它是比较复杂的,它会根据一个配置文件创建特定的目录并且做签名验证。我在微博APP里面寻找其他通过http传递的zip包,很幸运还有很多其他的zip包。在该zip包解压过程中通过路径穿越问题,只要让它正常释放之后的解压文件被我第二次zip打开的路径穿越覆盖掉,就可以达到代码执行劫持的效果。
(视频播放)
总结和思考
在漏洞预警发布之后,厂商纷纷修复了该问题,但没有向我们发出官方致谢,这一点让我们很郁闷。我发现在微博、论坛、网站上的开发人员对这个问题有探讨和反馈。看到他们的反馈之后,让我对这次安全事件进行了深一步的总结和思考。
开发人员在我们并没有发布攻击细节时,说这个条件非常苛刻,首先,APP需要使用zipArchive,其次,原APP下发的某个zip包传输过程没有加密,zip包也没加密。另外,原APP使用jspatch或者其他脚本本地没有加密,而且只要把脚本放到指定目录就可以了。另外,用户需要连上第三方WiFi。他觉得条件非常苛刻,要满足所有这些条件才会受到影响。我针对他们提出的问题这个进行了思考:
1、开发人员的猜测是zipArchive存在问题,而且APP刚好使用了zipArchive。实际情况并不是这样的,在APP审计时我们发现了并不只有ziparchive有问题,ziparchive衍生了大量的私有库,安卓的zip库同样存在类似的问题。这个事件发生之后,国外的团队发现问题,大量的java等全部存在这个问题,都是有影响的。
2、开发人员猜测APP的zip包传输过程中没有加密。首先可以肯定的是zip包传输过程中没有加密,但是zip包确实加密了,而且还在解压前做了签名验证。开发人员认为只要加密了zip包就可以保护APP了,其实这个是不存在的。
3、开发人员猜测原APP使用了JSPatch或其他执行引擎,且本地脚本没有加密,只要把脚本放指定目录即可执行。但实际情况是基本与猜测的情况基本相同,还是有区别的,不是把脚本放进去就可以了,如果没有通过前面的签名验证,这个路径是创建不产生的、是不存在的。只有通过正常的逻辑把这个路径创建之后,才可以去进行覆盖。
4、开发人员猜测用户连上第三方WiFi遭受攻击,我觉得用户连上第三方WiFi这个事情非常普遍,第三方WiFi会做非常古老的欺骗。开发人员可能认为它不是风险,但在用户使用时你没办法控制用户使用行为。
总结和思考,可看见实际情况与开发人员的猜测存在一定的出入,结合我自身的开发经验,思考我自己开发的项目中存在过的安全问题,发现做安全和做开发时,开发人员不知道安全人员在想什么。这叫“达克效应”,是一种认知的偏差,在某一方面的能力欠缺时错误的认为自己比真实情况更加优秀,认为只要做了zip加密就可以保护APP安全了。但在ZipperDown和微博中反映了,hotpatch相关代码的处理是完全没有问题的,但是其他开发人员在APP下载一堆zip包且未使用https导致了最后的问题,对软件开发和安全攻防中客观存在的情况,是一个比较贴切的解释和总结。
话说回来,开发人员的主要工作是开发软件,业务压力很大,精力有限。我作为开发人员经验让我明白在安全问题上犯下错误是难免的,所以开发人员可以多上看雪论坛或者去CSDN了解安全知识,减少代码里及设计上的安全问题。一些非常隐蔽的小问题,开发人员觉得不是问题的,但其是可以被利用的,这就需要专业安全团队帮助开发人员去审计了。
声明:本文来自看雪学院,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。