美文网首页
移动端安全iOS方向

移动端安全iOS方向

作者: Exia_L | 来源:发表于2017-09-04 17:24 被阅读795次

    以下内容为自己的一些经历和一些查阅资料的总结,希望能帮助到需要的人

    一 iOS上的加密思路

    问题

    这两天一直在想公司app的安全问题,因为发现很多app登录的时候其实是裸奔的,带着账号和密码,等塞进post 请求参数里,直接飞向了服务器。这本都是敏感信息,不应该这样轻易暴露在外边。以前所在公司,也吃过这种亏。之前也一直看过加密的问题,但是也没有深入的理解,这几天查了一下资料,所以稍微记录下使用的流程。以后真的用到这个过程时候,掉坑了再回头填。

    过程

    1、客户端将 username 和 pwd 做md5 处理,然后再加上客户端的AES key,将这部分内容通过RSA加密,传给服务器。
    2、服务器会通过一个私匙,解开登录传过来的数据,获得 username、pwd,和 客户端的AES key。
    3、登录成功后,服务器也回生成服务器端的AES key,然后将登录成功的状态 和服务器端生成的AES key,通过客户端的AES key进行加密,回传给客户端,完成这次登录的请求。
    4、客户端收到登录回调的数据,通过客户端自己的AES key 将数据解开,获得登录的状态和服务器端的AES key。获取了服务器端的AES key 之后,自己本地生成的AES key丢弃,并保存服务器端的AES key。
    5、以后需要加密的信息就直接通过服务器端的 AES key 加密,传给服务器。
    6、服务器可以动态控制AES key,这样伪造请求被发现后,也可以更换服务器的AES key。
    流程图


    hecvstyleRSA、AES -Process.png

    RSA、AES加密处理流程一些Tips

    1、RSA只在登录的时候使用。为什么只在登录时候使用,因为RSA加密有一些限制,首先他的密文长度只有117个字节,如果你需要加密的内容过长,那么可定会超过117,这样就超出了限制,无法完成进一步的处理。其次,RAS加密是需要时间的啊,骚年!普通内容,每次使用RAS加密,效率肯定不高啊。
    2、在解编码过程中,涉及到了base64,记住base64 超过一定长度会自动换行,拿到的base64 编码,记得去掉换行符,不然是解不出来的。
    3、用服务器的AES key原因就是可以动态的改变,如果一直使用客户端的AES key,一旦泄露之后,如果要修改密匙就只能APP升级了。

    二 iOS安全开发防护摘要

    前段时间集中时间写了一本《iOS应用逆向工程—分析与实战》,马上就要上市。我想大概会有一部分iOS程序员觉得:你所说的这种越狱平台的技术压根上不了AppStore,与我何干?不过我相信另一部分人肯定会有相当大的触动的。

    写作这本书的时候,所有目标都是集中在进攻方向上,而没有太多考虑防守。因为从逆向工程的角度,确实是非常不好守的:微信、QQ那样的聊天工具,聊天记录可以截取;支付宝、网银那样的支付工具,用户信息和密码可以截取;至于其它更多app,放到逆向工程的面前感觉就是一个在裸奔的小孩,哦不,一群裸奔的小孩。

    虽然知识从来都是矛与盾的关系,但对上了逆向工程,确实就易攻难守,不过,尽管是难守,总还是可以守一守的。下面从笔者的经验上来分别罗列一下遇到的问题,及某些app的实际对策。

    1、本地数据
    很多开发者喜欢用NSUserDefaults来存储一些全局数据,但是这些信息可以直接在app目录文件中读到,如果你也把username和password存在里面。。。当然,如果安全级别不高的程序,这么写也没什么问题;
    很多app也会存一些简单的数据到本地sqlite文件中,但实际上,完全可以使用加密sqlite的,当然,还是那句话,安全级别不高的程序,这么写没什么问题。

    2、网络接口保护
    现在绝大部分的app都已经是联网程序了,经典模式就是http+json,客户端一解析,再做的漂亮一点就齐活。然而只要架上Charles或是tcpdump,完整的url request+response就看的清清楚楚。有了这些url,你的网络数据就无密可保,尤其是一些资源型的服务,直接通过getList的模式就能把所有的数据抓回来。
    这种情况下,即使是https也没用,Charles轻松就能搞定,可以看相关的文章。而且即使不用Charles或tcpdump,直接用代码hook网络接口,一样能把数据拿到。

    另外插播一句:json是个好东西,它的展现就是一个Dictionary,数据呈现的非常清晰。但是它也绝对是最容易被盯上的点。设想一下,攻击者hook了接口数据,此时直接把json或Dictionary打印出来,信息是不是就一览无余了?在笔者的概念里,把Dictionary/json转成普通的业务对象再传递,即使被拦截,起码不会那么直观地被看到。当然了,这只能给逆向者增加一点麻烦,纯属细枝末节。
    笔者看过不少app,大概70%都是这种全裸奔的网络请求,比如“网易新闻”;剩下的会对url做一定的保护,比如加token和timestamp,如“36kr”,这样确实就把抓数据的难度陡然提升了;最“变态”的是“我查查”,他们直接把url做了加密/编码,这种情况下想要复制出来就需要大费周章,而且如果这种编码方式不是通用的,就更难逆向解析了。

    3、混淆
    混淆有两种模式,一种是对函数名做混淆,另一种是对代码做混淆,两种都直接增加逆向的难度,但是挡是挡不住的,尤其是逆向者还有大把的时间。

    4、程序结构
    在app这种小而美的领域中,如果代码结构也设计的非常简洁漂亮,实在是一件令人赏心悦目的事情。不过对于逆向工程,越是这种设计结构,越容易定位,有时甚至不用上什么大招,直接从.h文件名和函数列表就能初步定位想要关心的核心代码,如WhatsApp。
    而一个反例是微信,微信的质量水准是有目共睹的,不过想要对它进行逆向工程就是一件比较痛苦的事情,因为最新的5.1有3000多个.h文件,如此庞大的代码量直接将逆向工作量提升一个数量级。在笔者的分析过程中,经常会被一堆的Mgr、Event、Service给搅的心烦意乱。
    这2个app只是两个极端的比较,毕竟WhatsApp全公司才50人,一个iPhone版的开发者不过数人,结构自然清晰;而微信早已是一个庞然大物,各部门之间相互合作,一层层的代码库抽象封装好给其它组调用,即使是很简单的调用可能也要串3、4个场,不过这样也间接增加了逆向的复杂度。

    5、C或block函数
    现在iOS方面的逆向工具都是针对OC来的,而一旦代码以C函数或block函数来实现,相当于就采用了匿名函数,想要定位它就只能使用IDA,并且还很容易定位不准。笔者曾经在查看知乎日报的一段对token进行编码的问题上绕了很大的圈子,依然没有定准位,最后干脆放弃了,那段代码就是拿block来完成的。而且,如果是C代码,在IDA中看起来就不是易读的OC风格伪代码了,看起来也会比较累。

    总的来说,还是要看开发者比较在意哪方面的安全,才好考虑如何防护:

    1、想要保证程序中的信息不被截取
    几乎是不可能的,因为即使再加密,密文也总要变成明文供业务逻辑来使用,攻击者只要盯住这个点就能达到目标;

    2、想保护服务器的资源
    客户端在相当程度上只是一个UI展现,即使被破解也不是那么重要的,真正重要的是服务器端的资源,那么就要在网络层进行防护了。现在大家都比较喜欢用http,而且都集中喜欢使用AF、ASI等几个开源库,逆向者只要盯住这几个口,就能把来往的request+response全部获取,进而可以仿制一个客户端,此时服务器的资源也就全面开放了。同样的,使用AsyncSocket也是一回事。
    此时有3种防护措施:
    1)服务器控制,不允许同一IP/客户端频繁抓取数据;
    2)对url加上token、timestamp,甚至url编码,虽然碰上高手还是不能100%安全,但是破解者想要达到目的,就需要考虑付出的精力是不是值得了;
    3)传输数据加密,并且将加解密的代码层级加深,尤其是放到C或block函数中,这样又将安全等级提高了一级。

    3、想保护程序不被伪造或克隆
    克隆/伪造其实是件非常容易的事,甚至都不需要太多逆向工作,只要能把网络请求搞定,剩下的就是代码量、以及是否比被仿者做的更好的问题了。

    总的来说,客户端没太多可保护的空间,它应该就是个业务展现和数据解析的工具,与其花精力想防这个防那个,不如把精力放在网络接口的保护上,尤其是加解密代码提取到C或block中。
    以上只是笔者个人的一些经验,希望大家能多多补充。

    附:微信的安全防护措施,笔者认为是比较值得学习的,他们的步骤是:

    1、不在业务表现上做太多无用功
    除了代码结构比较庞大之外,微信没有做特别的动作;

    2、服务器控制
    所有的决断性的动作由服务器控制,几乎不可能靠通过篡改客户端的代码来获取更大的权限。笔者曾经针对每天20个漂流瓶的限制尝试扩大权限,但是即使把本地代码逻辑放开,在超过20个瓶子之后,再捞回来的永远是海星,显然是服务器控制住了。
    当然,本地LBS坐标是无法被服务器控制的,这也就是坐标穿越插件能起作用的根本原因。

    3、网络数据加密
    通过对网络接口的拦截,虽然能得到socket收取的二进制数据,首先是无法直接解密,其次是从那许多代码中找解密代码非常费劲,纵然加解密都能搞定,想伪造也十分麻烦,packet中包罗了相当多的信息,我估计就是把他们的代码开放给开发者,想理清这一部分都不是一件轻松的事情。

    4、登录唯一性
    即使能够伪造微信的请求,一旦登录获取数据,原账号就会被踢下线并且得到通知,这本身就是一个安全警告,说起来也算是服务器控制。

    如果开发者对于安全性的设计都能达到微信这一级别,安全级别就是比较值得信赖的了,但是这也不表示就解不出来,只要逆向者的水平达到熟练程度以上(自然是越高越好),并且愿意投入大量精力在某个他们认为值得的app上,几乎都能攻的下来。

    相关文章

      网友评论

          本文标题:移动端安全iOS方向

          本文链接:https://www.haomeiwen.com/subject/kwbejxtx.html