推荐序
前两天在「猫头鹰团队」的公众号看到这篇文章,于是我要了转载授权,推荐给大家。
本文的作者沙梓社和吴航共同编写了《 iOS 应用逆向工程》,文章中介绍的是一些基本的 iOS 领域的安全知识,但是由于普及不够,基本上没有被人们重视,希望本文能让大家重视到 iOS 的源代码安全问题。
另外预告一下,我认识的一个做移动安全的白帽子即将公开一个在非越狱手机上通过 App 绕过 sandbox 的 iOS 漏洞视频,并且计划发布一系列 iOS 系统安全方面的文章。我争取到了授权,并在我的公众号上同步发表这些文章,敬请期待:)
以下是文章正文,略有调整。
讲师介绍-沙梓社
湖北武汉人,《iOS 应用逆向工程》系列图书的作者,在 Cydia(最大的越狱 iOS 商店)上有 11 款独立作品,接受过 CSDN 的专访,书的英文版在 GitHub 上开源后收获了 2600+ stars,是首位在 WWJC 上发表演讲的中国人,以「提升中国 iOS 开发者在国际上的地位」为己任。
在很多朋友的眼里,iOS 逆向工程是一个小众、神秘的方向,为什么我会选择这个小众的方向呢?这要从我最喜欢的一首诗说起。第一次,我是在李开复的自传《世界因你不同》里看到这首诗,当时就感觉身心得到了非常强烈的震撼:
因为我感觉到自己就是这类人:如果有两条路给我选,我确实会选更少人走的那一条。我发现自己是一个刻意保持自己跟别人不同的人。
在初次读到这首诗时,我还没有开始学习 iOS。在从事 iOS 方面的研究后,又从乔帮主亲自配音的广告中寻找到了灵感,发现苹果跟我的价值观非常一致,就是要追求不同。因此,我更加认定 iOS 就是我的主攻方向。
我的成长之路,就是一条与众不同的未选之路:别人都在学「大众情人」Windows 时,我开始学「小众路人」iOS;别人都在学 iOS 正向开发时,我开始学 iOS 逆向工程。正是因为追求不同,我写的《iOS 应用逆向工程》成为了全球唯一一本 iOS 逆向相关书籍,而且有美国和韩国的出版社想要引进本书,打破了中国 iOS 知识产权零输出的尴尬纪录。我用自己的努力代表中国 iOS 开发者在国际上发声,而且为 iOS 主流社区所认可,作为中国人我感到非常自豪。
简单来说,我所研究的,主要是 iOS 应用层的逆向工程,对内核层的逆向工程只是稍有涉猎,没有入门。应用层的逆向工程,我感觉自己玩得差不多了,应用层的所有逆向工程相关问题,都可以用我那本书上介绍过的知识和技术得到解决,我觉得没有太大挑战性了,主要是劳动量问题。到了这个地步,我的规划主要分为 2 个方向:
-
继续从事内核研究,这个方向的终点是「越狱」(越狱即通过漏洞利用拿到iOS的root权限,代表了iOS技术研究的最高境界);
-
换个脑子,用一些非技术能力武装自己,让自己成为一专多能的人才。这个方向的终点就是创业。
当然,很多朋友会问,IT 人员创业的普遍做法,都是去 BAT 这样的互联网公司干 2 年,观察一下他们的玩法,然后拉一个团队出来干。你问啥不这么干呢?主要是碰到了一个很好的项目。大公司一直都在那里,想什么时候去都可以;而好项目却不常有,机会过去就过去了,不等人,所以我在准备并不算充分的情况下选择了创业这条路。
交代完了我的背景,咱们可以进入正题了??
大意是「通过研究现有功能的实现原理,理解并融会贯通,在此基础上实现(甚至增强)这个功能。」也就是说,不是照猫画虎,而是师夷长技,「借刀杀人」。
在我的理解里,逆向工程是一种工程师式的高级思维方式。给你水、面粉、糖、芝麻,让你做烧饼,这是正向工程;给你一个烧饼,让你分析出它是由多少水、多少面粉、多少糖、多少芝麻组成的,这是逆向工程。也就是说,根据图纸制作实物的这个过程是正向工程,而根据实物倒推图纸的这个过程则是逆向工程。乔布斯曾说「Good artists copy; Great artists steal.」逆向工程有异曲同工之妙。
举几个通过逆向工程师夷长技的例子:
-
通过逆向工程分析instagram滤镜算法。一个人可以“steal”一个滤镜算法团队的工作成果;
-
研究微信的网络传输协议,就像@58沈剑 在博客里说到的那样。就我目前对微信九牛一毛的研究来说,就已经发现了一处可以进一步节省流量的地方,但是估计是因为历史遗留问题,这块代码不好动;
-
看看1Password做了哪些防护。1Password是专门用于保存密码的,类似于保险柜,安全系数必须很高,它把我们的密码存在了哪里,通过什么方式加密?这些都是值得我们学习借鉴的地方。
除了去学习别人的长处,逆向工程还可以发现自己和别人的短处:
这种低级错误,星巴克可以犯,但1Password不能犯;这取决于你的产品定位。这个错误当然是通过逆向工程发现的。
这是某世界500强企业犯的,通过HTTP协议明文传输用户手机和密码的低级错误:
这是某突破3亿用户的移动App:
把传输协议的密钥硬编码在代码里,有逆向工程基础的朋友可以轻松还原整套网络传输协议。淘宝上一堆堆的这个刷榜那个刷赞,就是这个原理。
阿凹(猫友会吉祥物,一个微信机器人),是「借刀杀人」最典型的运用之一:
阿凹的实现原理,简单说,就是通过逆向工程的方式找出微信iOS客户端的收发信息等私有接口,然后基于自己的逻辑调用这些接口,实现针对特殊事件的自动化应答功能。
我个人最常用的iOS逆向工程工具主要有这些:
-
dumpdecrypted:将苹果加过密的App砸壳。通过AppStore处理的App,都是加过密的,不能直接进行二进制分析,需要先解秘,业界称为「砸壳」。它的原理是等App完全加载进内存,得到解密后,再把解密过的内存给dump出来,形成解密后的二进制文件,可以直接分析。
-
class-dump:导出MachO文件里的ObjC类及方法定义。因为ObjC是一门强烈依赖于运行时的语言,它的文件类型是MachO(类比于Windows里的PE文件类型),MachO里存放了大量运行时需要用到的信息,从中可以收集整理,还原出一个App源代码里的ObjC头文件。
-
CydiaSubstrate:将第三方动态库注入进程。它是越狱插件的存在前提。在iOS开机时,会把特定目录下的所有库,给加载到指定的进程里,俗称「hook」或「钩子」。
-
Cycript:用JS语法写ObjC方法。这是Cydia之父Saurik发明的一门语言,我个人主要用它来测试私有函数。
-
Theos:越狱插件开发工具。是我的书序作者DHowett开发的。iOS正向开发用Xcode,逆向开发用Theos。
-
IDA:全平台反汇编、反编译工具。搞技术的一般都听说过这个软件,就不多介绍了。
-
Hopper:OSX反汇编、反编译工具。比IDA便宜了1000倍,但功能跟IDA差不多;主攻苹果系操作系统。
-
debugserver + LLDB:动态调试器。是大名鼎鼎的「苹果版」GDB。
class-dump的效果,图中显示的是新浪微博App的所有头文件:
Cycript的效果,可以看到微信星号密码的明文:
Theos开发插件的运行效果:
所有进程的[NSDictionary dictionaryWithContentsOfFile:]方法均被「hook」,可以随意篡改。
IDA的效果:
对于熟悉汇编语言(图里是ARM汇编)的朋友来说,所有未加密的二进制文件,均等同于开源。这是什么概念,做技术的都懂。
接下来我简单介绍下阿凹的制作流程:
核心在于找到收发微信消息的函数,然后加以修改利用:
-
用dumpdecrypted给微信砸壳,解密出的文件近50M:
-
class-dump出微信的所有头文件,近7000个:
-
定位到收消息的View,进而定位到V对应的C,找出逻辑层的收消息函数。
-
定位到发消息的按钮(也是一个View),进而定位到对应的C,找出逻辑层的发消息函数(这个过程没法用截图表现出来,所以我只简单描述下)。
-
组合收发函数,完成阿凹的逻辑,最后写代码:
问题及讨论环节
【问】沙大神,如果我成功找到了一个应用的加密函数,然后剩下的工作就是把它翻译成OC语言,这个过程有什么技巧么?我ARM汇编没怎么接触过,除了硬着头皮上,有木有什么捷径= =!
【答】如果你是土豪,那么可以购买IDA pro,1年十几万上下。可以把二进制文件给反编译成C语言。如果你不是,可以500块人民币购买Hopper,Hopper支持32位ARM汇编的反编译,直接反编译成C语言
【问】SOGA,也就是我需要从一台ARM v7的机器拿到二进制文件,之后采用这种方法对么
【答】是的,买一台二手iPhone 5即可
【问】你好沙神,比如说我用SQLCipher对用户的聊天记录SQLite进行加密,逆向工程能破解这个本地化的库文件么
【答】可以破
【问】那就是SQLCipher其实也不是绝对安全
【答】只要这个库在本地,可以被你的App解密,那么我就也可以解密;如果这个库在你本地没法解密,那我可能也没法解密。微信本身提供了红包功能,阿凹就可以抢红包,只是这个功能我没开放出来,破坏游戏平衡了;微信本身没有提供冲厕所的功能,所以我也没办法实现。
【问】额,意思 那就是只能看逆向者的三观了
【答】是这样的,这是把双刃剑。GitHub上一个复旦大学生开源的Android抢红包代码,1000多个star,洋洋洒洒几千行代码,我可以50行以内搞定,我只是觉得开源出来没啥意义,就算了
【问】那我又得问正向问题,就没有级别比较高的用户本地数据全保障方法了么
【答】参考支付宝和1Password
【问】能给讲下支付宝和1Password大概是怎么处理的么
【答】我也没有研究过,因为暂时用不到……
【问】阿凹回答问题的答案是调的什么资源?还是通过自己分词得来的?
【答】是用的图灵机器人。微信本身只提供了消息收发接口,发的是什么消息,是由图灵机器人决定的。我本来打算加入语音识别功能的,用科大讯飞,但是现在太忙了,没时间,就先搁置了??
【问】既然说到微信抢红包,沙大神我再问个问题。我猜想微信抢红包和发送聊天消息有点类似,通过检测红包发送消息和找到红包点击函数来快速抢红包。那么之前我也见过有人因为抢红包被微信发现禁用抢红包功能7天,请问沙大神,如果你是微信开发人员,你会采取什么手段来防范逆向开发人员
【答】这取决于用逆向工程干什么,如果是写个阿凹这样的机器人,我觉得无伤大雅。如果是抢红包,那我能想到的一个直观防范方式,就是如果发红包和抢红包的时间间隔非常短,比如1秒内,那么说明是用外挂了。另外就是把这部分代码写得难懂一点,那么逆向工程的难度也就大一点。
【问】我理解,理论上逆向工程都可以通过找到对应函数完成应用原本的功能,比如点击事件等
【答】是这样的,矛和盾总是没有止境的,只是看逆向工程付出的代价多大了。提高逆向工程的难度,让逆向工程师觉得不值得,是最好的防范方式。苹果防越狱,就非常高明,我把你们越狱社区最好的点子全都学习到了正版iOS里,用户觉得苹果越来越好用了,越狱越来越没有意义了。越的人少了,高手觉得没意思了,自然就防住了。
【问】嗯,那么能简单介绍几种常用提高逆向成本的正向开发手段么
【答】用C/C++函数写核心功能;关键功能函数名起个完全不相干的东西;编译MachO时加上ptrace、__restrict标记等方法;Swift/ObjC混编。这几个方法,可以防住绝大多数脚本小子了。
【问】我以前看过一本安全的书说用C++写然后代码用大量模版,逆向人就会疯了,是这样么?
【答】C++确实不好逆向
招人
沙梓社在上海创业,现在找靠谱java后端,找的火急火燎。这里有简介:http://iosre.com/t/30-ios-hacker/1618 和他的2015年终总结:http://iosre.com/t/topic/2523 如果大家在上海有认识的靠谱java后端,麻烦帮我引荐一下,叩谢!