iOS逆向(五)总结篇

  1. iOS安全开发防护摘要
  2. 开发者在意的安全防护
  3. 微信的安全防护措施
  4. 行业状况
  5. 技巧
  6. 读《iOS应用逆向工程》梳理

最后一遍,总结一下关于安全开发的攻防要点,借鉴一些经验,记录一些小而黑的技巧,还有我读小黄书后的知识点梳理。

iOS安全开发防护摘要

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风格伪代码了,看起来也会比较累。

6、代码中的关键数据
关键数据写在代码里,可以保存的是加密后的数据,使用的时候才解密处理。
密钥要定期更换。比如3个月或半年换一次,如果密钥是从接口通过非对称加密获取的,直接修改服务端就可以了。如果密钥是写在代码里的。就等APP升级新的版本的时候,新版本的APP和其对应的接口版本都修改为新的密钥就可以了。旧的接口版本和APP版本还用以前的密钥,等强制更新的时候才会失效。如果一个APP 一个密钥用上几年都不变 ,是很危险的。离职的人员都可以直接用以前的代码来获取相关的数据。特别是支付相关的,有的服务端甚至没有去校验支付的金额或其他数据,导致离职人员用1分钱可以买到任何价格的线上产品。

7、代码方面
在release环境下NSLog不要打印日志,否则iOS系统日志里都可以查看到,在.pch文件中加下面的几行代码就可以解决

#ifdef DEBUG
#define NSLog(...) NSLog(__VA_ARGS__)
#define debugMethod() NSLog(@"%s", __func__)
#else
#define NSLog(...)
#define debugMethod()
#endif

而Swift中打印要用print。AFNetworking的allowInvalidCertificates属性要设置成false,validatesDomainName属性 设置成true。否则HTTPS通信就可以被解密。一般开发的测试环境的HTTPS不是CA颁发的,而是自签名证书,访问的也不是域名,而是IP。所以可以在测试环境忽略证书和域名

#ifdef DEBUG
        manager.securityPolicy.allowInvalidCertificates = YES;
        manager.securityPolicy.validatesDomainName = NO;
#endif

开发者在意的安全防护

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

以上引自这里

行业状况

爱加密以安全加固作为业务销售,为客户提出了各种安全方案,这里可以作为一个方向了解,地址

技巧

绕过ptrace反调试
http://bbs.iosre.com/t/debugserver-ptrace/8037

反调试
http://iosre.com/t/topic/8179

读《iOS应用逆向工程》梳理

image


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 mingfungliu@gmail.com

文章标题:iOS逆向(五)总结篇

文章字数:2.6k

本文作者:Mingfung

发布时间:2018-09-13, 22:39:05

最后更新:2018-09-13, 23:22:35

原始链接:http://blog.ifungfay.com/iOS/iOS逆向(五)总结篇/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

宝贝回家