登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

演讲实录——Android应用安全提升攻略 [复制链接]

2019-5-10 10:09
九霄逆鳞 阅读:163 评论:0 赞:1
Tag:  

本文来自2019安卓巴士开发者大会现场实录,由于录入匆忙,内容可能存在偏差,欢迎大家扫描文末二维码查看现场实录视频和下载大会完整PPT。演讲人:侯海飞



侯海飞:大家好,我演讲的主题是《Android应用安全提升攻略》,上一期我一个同事做了VMP加固原理和攻击策略的分享。VMP保护方案的开发,对开发者的安全技术要求太高,且开发周期会很长,个人感觉对大家的帮助可能不会太大。所以这次分享,我想给大家带点更实际的东西,在应用开发过程中,有哪些安全方面的技术点需要注意,以及如何解决,如果不能解决,有哪些渠道可以获取帮助。



我会从三个方面来讲。第一是安全风险案例以及常见的安全隐患,让大家对应用感觉有个感性的认识;第二是应用安全活动周期,包括安全开发、应用审计、安全增强、渠道监控;第三是应用保护的常见策略,从待保护的目标是否为源码,区分为应用加固和源码混淆两块内容。



分享几个安全风险案例,这三个漏洞已经修复,一个是饿了么,网络协议数据加密被人破了。这是2015年暴出的漏洞,当时饿了么的开发已经有了些安全意识,将加密过程放在native层实现,但是对加密逻辑并没有保护,随着当前native逆向工具(如IDA)和相关方法的普及,native层逆向的门槛也在逐步降低。我们部门有不少客户来找我们做应用安全保护,大多是类似的关键逻辑被人破解,导致被薅羊毛。对此,涉及核心业务的开发者,需要对此给与足够的重视,一旦出了问题,可能给公司的利益造成极大损失。


下面一个是支付宝漏洞,这涉及了一个跨域访问的漏洞,老版本的Android系统(4.2以下版本),这个访问权限默认是开的,如果开发者没有主动关闭的话,这个漏洞相当于一直存在。当时暴这个漏洞的时候,支付宝的支付码被攻击者获取,并可直接支付,直接造成了用户的财产损失。

最后说一个照片恢复的应用。类似照片误删恢复的应用,市面上都是要付费的,当时我看了一下主流恢复类APP大多找第三方安全厂商加固,这些加固的应用脱壳起来还是比较费力复杂,为了给大家做简单的演示,我找到了一个没有做防护的,这里给大家展示一下直接的攻击过程。



介绍一下基本的业务场景,点击搜索照片,找到照片后,进入付费流程,付费成功之后会恢复目标照片。这里显示的是用户取消付费。攻击的时候这个提示是一个突破口,据此提示,找到了它的付费的控制流。逆向app源码,发现开发者的代码写的还是非常好,完全达到了自注释的要求,根据函数名称可以猜出付费控制流,所以当时的开发者还是非常优秀,但是他没有安全开发的意识,连基本的代码混淆,字符串混淆都没有做,直接导致攻击者可以轻松的找到核心逻辑控制流并修改,默认走到了付费成功的环节。



这里我大概介绍一下相应防护策略,其实我自己做完了攻击之后,通知了作者做安全防护。当时找这个素材的时候,特地去核实了下,他已经做了防护。从刚才的应用基本流程,可以看出那个APP是没有服务端,核心逻辑全部放在客户端是极为不安全的做法,这里可以将扫描到的照片信息以传到服务端,待用户付费后,可以把这些信息再下发给客户端,能够达到一定的安全防护效果,不至于攻击者更改一下付费控制流就被破解了。


这里还有一个是字符串加密,代码的明文字符串,需要加密,防止破解者直接搜索到线索;重打包这个也是一个点,启动签名校验,非原签名则直接挂机,或者无法正常运行核心逻辑;核心逻辑抽取到native层实现,增加逆向门槛。逆向入门者学习一天,就可以开始逆向java层代码,但native层应该还不够。代码混淆,也是很重要,核心逻辑抽取到native层,也仅仅是增加了一点逆向门槛,需要配合native的保护,才能达到好的防护效果。后面会给大家推荐native层混淆的方案。



安全隐患这里我们汇总一下,直接看图, App可被逆向,轻易获取代码逻辑,进一步导致控制流被hook,防线被破;可二次打包,APP可被修改, 被套壳加入攻击者代码,重新打包发布;密码学误用,客户端APP代码中使用了不安全的密码学实现,例如固定硬编码的对称加密,ECB模式的对称加密,CBC模式中IV固定等;敏感信息泄露,客户端APP代码中泄漏敏感数据,如认证使用的共享密钥、不应被暴露的后台服务器ip地址等;通信数据明文传输,客户端APP与服务器端交互的数据通过明文的通信信道传输,或者加密传输,但数据依然可以被解密;还有日志信息泄露,可调式之类。这个可调试,多说一点个人经历。以前在某大公司开发了一个业务,公司的安全部门会对代码做检查,查看有没有基本的安全漏洞,如果你把加密过程放在代码里,会被检查出来有风险,安全督查人员会指导开发者把加密的过程拆分,放在不同的文件,加上一些其它步骤让逆向者多费时间。这样的操作,对初级的逆向者可能会有一点点用户,但是逆向的人如果能调试app,那他根本就不需要知道加密的过程,直接把加密的接口调起来之后就可以了,不用管过程。所以这个反调试也是一个安全技术点。

    


下面我们说一下安全开发活动周期以及开发过程当中有哪些点是需要注意的。开发之前比如你这个业务规划好了,要开发哪些功能,开发这个功能的过程当中,或者说是规划之前就应该有意识做安全方面的工作,哪些地方可能会被逆向者利用,比如网络数据传输怎么保护,都是安全防护点。

应用开发好了之后我们想知道应用到底有没有漏洞,我们可以使用一些漏洞扫描工具,其实这些扫描工具一般都是静态的,速度比较快。安全厂商都会提供这个漏洞扫描的功能,一般也都是免费的。



这里是一些常见的安全点,大家可以看一下,这里有密码输入、加密算法与秘钥存储、数据通信、运行环境安全、应用签名校验、核心逻辑保护、调试日志清理、应用敏感数据保护等技术点,大家可以自己看一下具体的攻击点和开发建议。



这里说一下安全扫描和渗透测试的事情。前面我们说的跨域访问漏洞,可以通过安全扫描判断是否有此漏洞,我们可以参考一下公安三所的扫描结果,这个是我接触到的最全面的安全扫描。扫描的方法基本上是静态扫描为主,这里有很多公司内部有安全部门会对你的APP进行扫描,扫描之后会让你进行修改。动态扫描大部分厂商还是没有提供的,比如可调试、进程注入这些功能基本上都是要动态检测的。渗透,基本上都是人工渗透,这里一般都是找第三方厂商,它是针对目标场景,比如你是一个支付应用,你的支付密码和协议保护这些都是一个关键的覆盖场景。渗透周期的测试也是比较长的。



这个是2018年金融类应用高危漏洞,大家可以大概看看这些常见的漏洞项目,有个感性认识。其实并非所有的漏洞都需要修复,漏洞检测大多是静态检测,开发者可以根据实际的情况选择。

漏洞的修复,这些检测项,通过普通的加壳都是可以从表面上解决,因为加壳后,应用的代码已经被隐藏,静态检测是检测不到的。但是,加壳一般只治标不治本,且简单的加壳容易被破解,开发者自己研究加壳也比较费时费力,且适配安卓的版本会相当的麻烦。在下面会推荐一套方案,大家是可以研究的。第三方厂商会提供这些相关的业务,帮助开发者解决这些漏洞,这里不多说了。



这里你发布之后需要监控应用到底有没有破解和有没有损害公司的利益,这里是我们公司某部分对应用盗版的数量和盗版的渠道分布,开发者需要根据监控数据做分析,需要做相应的安全策略升级和对抗。



最后我们说一下Android加固常见的策略,包括应用加固和源码混淆。首先我们看应用加固策略,一个是直接对应用二进制文件进行加固, DEX文件和SDK文件是一致的,安卓sdk是将dex和资源打包起来,这里主要谈谈dex文件的加固。SO文件主要涉及一些函数隐藏。



下面看一下这个是加固方案迭代的周期,第一代是最基础的混淆,第二代整体的加固,把原包的DEX做一个加密存储,启动时解密load原dex,相当于app外面套一个壳。

普通加壳现在破解的工具已经非常多了,研究也了没有用,这里还有一些兼容性和应对Android碎片的东西,如果自己研究会很麻烦。还有一个是拆分DEX加固,这个就是前面的基础上做了一个函数上的抽取,加密保存,并且在你运行的时候会申请内存,对原函数做patch。这有一个好处,就是被保护的函数,内存不是在一个连续的空间,这一个方案也有相应的破解工具,安全强度也可以忽略。

虚拟机加固(VMP)是去年我同事分享的内容,主要是替换函数指令,通过定制虚拟机解释器去执行替换指令后的函数,这套方案的保护效果是挺好的,方案发布以来还没有碰到被破解的情况,这个方案一般来说都是局部加固,涉及到一些执行效率的问题。



最新一代的加固是java2c,强度还是很高的,因为他把java指令转成了native指令,并且转换之后还有一些控制流伪造的功能,你原来的功能它这里会伪造几十个控制流,让逆向的人非常痛苦。



SO加固这里导出函数有369个函数,加固后它只有42个函数,其他的用户自定义的都是可以做加密的隐藏的。原先老的方式是基于段的加解密,去年有一个人写了本书是关于Android逆向的,里面讲了一些Android加壳的基础方案,建议大家不要看,因为完全没有用,强度太低,开发后还要适配安卓各个版本。



这个是Java的代码混淆,针对一些逆向的IDE环境是有一定效果的,建议大家可以考虑做一些中文混淆,这个很容易实现,并且的确有效果。



这个是我刚刚说的C++代码的混淆,这个是原来的函数逻辑,你保护之后这个逻辑变成了这个样子,控制流大幅度伪造,会让攻击者痛不欲生,遇见这样的保护,我们基本也不会去逆向。控制流伪造,大家可能也有疑问,会不会影响运行效率。这里的确会影响运营效率,所以一般也只是对核心的一些功能做保护。



这个是混淆的过程当中加的一些字串的保护。



下面是重点内容。c/c++代码混淆工具,逆向对抗利器—LLVM。LLVM的处理过程是一般的编译器都有的三个过程,包括前端、优化器(中间件)、后端。通过这个优化器我们可以实现各种效果,例如代码控制流扁平化,虚假控制流,字符串加密,符号混淆,指令替换等,刚刚的控制流其实是做了一个虚假的控制流优化。



H5脚本混淆大家可能也都会做,很多人觉得还是没有什么用。如果没有混淆,刚入门的攻击者都能看懂你的实现逻辑,但是如果根据语法树做了逻辑混淆和字符串加密,至少能让攻击者难受,逆向没那么轻松。H5脚本的混淆很多的IDE环境都可以配置,大家可以找一下,这里我不做介绍。

最后我总结一下,安卓开发过程中,核心逻辑一定要放在native,20人以上的团队个人建议,分配人手搞安全,搞LLVM,做优化器。


以上就是我所有内容的分享,谢谢大家。




现场PPT分享:

      关注【安卓巴士Android开发者门户】公众号,后台回复“420”获取讲师完整PPT。


大会现场视频小程序:




欢迎前往安卓巴士博客区投稿,技术成长于分享

期待巴友留言,共同探讨学习


分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部