« August 2015 | Main | October 2015 »

September 19, 2015

说说 XcodeGhost 这个事

最近 XcodeGhost 这个事挺火的,简单说就是有人在 Xcode 里植入了木马,让用这个被修改过的 XCode 编译出来的 ios app 都被插入了一些代码。由于 XCode 几乎是生成 ios app 的唯一手段,且墙内的同学各种诸如用 baidu 搜索,迅雷下载等坏习惯早就根植在基因里了,导致了这份被种马的 XCode 在最近半年里广泛传播,污染了一大批国产 app 。

我这里就不提那些中招的所谓大厂了,如果经常听我扯淡的同学早就知道我的观点:即便是大厂,有安全常识的人还是少之又少、反而是所谓大厂因为管理更困难(好多大厂到管事的那级的人更跟不上知识更新),犯安全错误的机会就更大。

这种从非官方渠道下载软件使用而中招的事情又不是第一次了。上次 putty 被种后门 的事情过了也没多久,好了疮疤忘了痛,对吧。

种马的手法其实也不新鲜。有点年纪的程序员读书时,课本上一定教过:计算机病毒有四种形式,最后一种就叫源码病毒,感染附着在编译器中。只是估计很少人见过,后来课本就删掉了。其实呢,这个说法的源头是 Ken Thompson 在 1984 年图灵奖演说上提到过的恶作剧。老实说 The Ken Thompson Hack 的手法比这个高明的多。

XcodeGhost 的技术细节就不分析了,网上一搜一大堆。我想说的是这次这个东西危害问题。

这玩意有没有害?当然有。你以你名义发布的程序被人插入了一段你不知道是什么的代码,当然有危害。因为用户信任你才用的 app 。你也不希望你的 app 的用户的信息被不知道什么人获取。因为理论上,你的 app 可以了解的信息,这段代码都可以得到。一旦你在 apple 的账号系统之外又自建了用户系统,那么这个第三方(你自建的)系统的安全性一定出现了漏洞。

这也是苹果从来都不赞成第三方 app 自己搞一套生态的原因之一。你没有系统级的权限,本身就在安全性上打了折扣。

但是,你的 apple (icloud) id 及其密码到底面临多大威胁?我认为危险是完全可控的。

首先:在 ios 系统中,icloud 密码是很高优先级的东西,ios 设计人员再傻也知道要重点保护它。所以,如果通过正常的渠道,在 ios 中输入密码,即使是通过被感染的 app ,也是不可能通过程序获取到 icloud 密码的。唯一的手段是模拟一个输入密码的对话框引诱用户输入密码来钓鱼。

但 ios 是如何从设计上去解决被钓鱼的安全问题呢?

没错,app 可以自己画出任何外貌的对话框,用户无从分辨是 app 画出来的还是系统画出来的。但有一点可以提供安全保护。那就是 icloud id 本身在 ios 中同样是高安全级别的信息,和密码一样,禁止 app 获取。所以你注意到没有,没当你使用 ios 的时候,系统要求你输入 icloud 密码,对话框上都会写明需要登录的 icloud id 是什么。而不会让你在那里去输入 icloud id 。唯一可能要求你输入 icloud id 的地方就是 app store ,在别的 app ,哪怕是苹果自己的 app 里都不会做此输入要求。这赋予了用户分辨钓鱼对话框的能力。

一旦有对话框要求你输入 icloud id 时,你都应该警惕是不是钓鱼。作为这种反常的输入要求,你可以回忆一下最近半年有没有遇到过,如果不确定,还是把 icloud 的二步验证打开好了。

说到这里,微博上有同学就此反驳说。不是所有人都有这个安全意识,尤其是中老年用户。我想说,就我认识的同学的父母,更多的把 icloud id 是什么都忘记了,哪里谈的到输入。几乎 iphone/ipad 交到他们手上后,他们就没有接触过 icloud id 的概念,能记得密码就不错了。

用户自己的安全当然总有一部分是靠自己的,如果系统让你输入啥你就输入啥。还用的着骗你的 icloud id 吗?直接伪造一个支付界面,让你输入银行账号密码不是更直接。这,就是为什么苹果系统不让 app 自己搞支付接口的重要安全考虑之一了。

我更想吐槽的是,国内安卓平台的搞法,各个 app 都把支付平台用 sdk 接入到自己的程序里的方法,根本就是作死。别说钓鱼了(画一个一摸一样的界面还不容易?),同一进程下,即使 sdk 不是你写的代码,你也有一万种方法知道那些输入框里输入了些啥。没有沙盒隔离,不在独立进程去做支付,是无法从根本上解决安全问题的。这也是为什么在 google play 被墙后,我拒绝使用安卓设备的原因之一。

ps. 对比看看国内各个支付平台的设计。有几个是把保护用户账号名作为安全设计点的?国内做平台设计的人的安全常识可见一斑。


今天,有人在微博上声称自己是 XcodeGhost 的作者,并坦言除了植入广告,并没有做什么特别有危害的事情。收集的信息仅限于作为普通 app 人人都可以收集到的。有同学核对了开源的代码,和之前逆向工程的结果做比对,认为比较可信。

我对此结论基本相信,虽有少部分说法保持怀疑,但我相信即使我用过那些被感染的 app ,我对自己的 icloud 账号的安全还是信任的。我在微博上是这样评价的:

对于 XcodeGhost 这事, 我想说, 你的 app 不过被人插入了几行不是你写的代码发布到了 app store 而已, 能不能干坏事要看 ios 的安全机制; 当你接入腾讯 sdk 等类似代码时, 成吨的不知道是啥的代码被插入你咋就不担心呢? 相比之前 360 app 利用漏洞去躲避苹果审核那些私有 api 调用, 这次安全的多啦.

为什么我要把被感染 xcode 植入代码和接入第三方(比如腾讯的)SDK 相提并论?那就是因为 app store 本给了用户你最后一道信任防线,由他来证明 app 是谁开发的,而你来最终决定是否信任。而国内渠道要求乱接 sdk 的风气,早就破坏了这道防线。你用的所有国产 app 里都有可能嵌入了不是他家开发的代码。

这次被插入的代码,即使没有公开源码,规模也很小,很容易逆向分析;相比腾讯 sdk 容易多了。即使你相信腾讯公司的节操,你又如何信任由一堆没有安全常识的人写那成吨的不可能被公开审核的 sdk 代码里没有安全漏洞可以被黑产利用呢?

安全不能全寄托在开发者的素质上,无论是有意还是无心还是过错,都有可能插入非用户期望的代码。这个信任最多是一个安全环节,前面还有苹果商店的审核、ios 系统的沙盒等多个关卡。

ps. 不用 SDK 的话,正确的做法是什么?第三方平台提供接入手册,告诉接入方用什么协议去跳转到相关 app 里去认证。如果用户没有装你的 app (qq 微信这些) ,就应该打开系统的浏览器做 web 授权。


说起苹果商店的审核制度,没有技术背景的同学总觉得这事或多或少要怪苹果审核不力。这是个严重的误解。苹果审核没有能力去靠静态分析,和有限的人力去了解一个 app 到底能干什么时候,会弹什么窗口。就算你拿源代码去审核他们也办不到。

苹果审核只能确定你的 app 调用了哪些系统 api ,这些被允许调用的 API 是被安全认证过的,基本不会逃逸出沙盒去获取非法信息。这就是为什么苹果要在 ios 上禁止 JIT ,禁止动态加载原生代码的原因。一旦允许 JIT 或动态加载原生代码(你可以过审后从网上下载一段未被审核的代码运行),app 就可以在运行时调用那些被禁止的 API 。从这点看,之前 360 发布的 app 利用漏洞逃避苹果审核自己的应用内调用私有 api 的行为危害大的多。

当然,审核并不是 ios 最后的安全手段,最关键还是 ios 自身的沙盒隔离。审核只是多做一层防护,相当于开个白名单,减少沙盒的安全漏洞被利用的可能性。至于沙盒这最后一道(也是最重要的)防线,就要求用户你不要去搞什么越狱啦。


昨天,有同学给过我一个链接,说其实未越狱的 iphone 也可以被钓鱼。

在非越狱的iPhone 6 (iOS 8.1.3) 上进行钓鱼攻击 (盗取App Store密码) 其中的截图还被人危言耸听的拿出去作为这次 XcodeGhost 可以被用于钓鱼的证据。

其实无论你有没有特别的技术背景,只要中文理解能力够,就可以读懂上文中的技术重点。

它其实说的是一个漏洞让程序可以后台将对话框弹到别的应用里。但这里有一个重要的前提条件:安装钓鱼 app 到目标设备。在这个漏洞还存在时,这个钓鱼 app 也无法逃过苹果审核的静态分析一关。

另外,钓鱼成功还依赖钓鱼者知道用户的 apple id ,而这点目前依旧无法办到。让我们看看文中提到的非法获取 apple id 的 CVE-2014-4423 的简单分析。我们可以知道几点信息:首先,这个安全漏洞在 ios 8 就补上了,其次,利用这个漏洞需要调用私有 API ,依然是过不了苹果审核的。

这些都不可能用于目前的 XcodeGhost 。这正说明了, ios 的层层安全措施有效且必要。


无论如何,作为一个中国人,若想尽量保障自己的隐私安全,加强安全意识还是非常重要的。选用安全的操作系统(远离国产安卓平台),勤快的升级,小心选择不会被社工的密码,且保护好你的账户名。还有,尽量远离国产软件。

September 15, 2015

最近 blog 系统出了几个问题

今天有同学反应 blog 无法留言了,说是不能创建新文件。我试了一下,果然如此。可是 ssh 上去看,磁盘空间还有 30% 。猜想是 inode 用光了,用 df -i 看了一下果然如此。

但是一下子没想出来是什么东西产生了大量小文件。只好用二分法筛选目录去看。结果发现是很多年前用 php 写着玩的一个留言本,每次留言都会产生一个新文件。这个留言本没有公开 url ,不知道被什么爬虫爬过了,累积下来居然留了一百万条垃圾信息。删掉后一切正常。

另外,最近间歇性的出过 web 访问无法返回的现象。经过排查,是原来用的一个 wiki 系统的某个 bug 导致的死锁。那个系统虽然是开源的,但早就无人维护了,这几年我试着修过几个 bug ,这次真的懒得修了,直接把链接从首页去掉。

最后一个问题是 blog 的留言处理的很慢(导致很多同学多次提交),不知道是不是数据太多了,原来的 movable type 的老版本结构没设计好导致的,一时也不想追查。看来是时候换个自己写的 blog 系统了。用这些停止维护的老开源系统真心不如自己搞啊。