移动端安全iOS方向

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

一 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上,几乎都能攻的下来。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,563评论 18 139
  • 伴随着移动产品广泛应用与快速发展,移动客户端的安全问题越来越受重视。我这里主要谈谈iOS移动端的安全架构设计。 一...
    火星抄手阅读 3,809评论 2 24
  • 一部《三生三世》把爱情演绎的很纯粹,很动人,,拥有一切美好的夜华,只爱白浅一人,其中充满了那么多的小心翼翼与关怀...
    lovelycat0阅读 203评论 0 1
  • 初见 暗恋 时光 深情 如果是你 我愿意等,花开花落 ...
    顾思思呀阅读 1,247评论 5 2
  • 风来,水起 焉知薄荷塘中 清影映方斜 那岸上葱葱 只见花开,不见人来 骤风,骤雨 那一方晴空突变 楼高欲望断 背影...
    临安晓晓阅读 285评论 0 1