1、前言
说到Mac App安全,大部分人用户可能都未曾遇到过恶意程序的威胁,所以导致不够重视。从最近接到多名Lemon用户反馈电脑发烫、风扇狂转以及活动和监视器和Lemon都会出现闪退情况,通过定位发现是几年前‘挖矿病毒’又开始被不法分子恶意利用了(备注:如有用户遇到这些情况,可以参见Lemon吐槽官网提供的解决方案Lemon - 吐个槽)。但是从这可以发现,即使是普通用户也有遭遇恶意程序威胁。那么本文简单介绍Mac如何一步一步提升系统的安全性以及用户如何预防恶意程序。
2、Gatekeeper
对于Gatekeeper可能很多人比较陌生,但是说到系统设置里安全性与隐私的设置项目,大部分都应该设置过。见名知意,Gatekeeper即为电脑的守门人,对没有‘合法身份’的App进行拦截。对于Mac电脑的用户,大部分是从App Store或者网络下载自己需要的程序。基本上会遇到“xxx软件已损坏,打不开,您应该将它移到废纸篓这样的提示”。于是大部分人百度之后得到的方案是sudo spctl --master-disable
。这样给予了那些没有经过苹果信任或没有签名的程序加载的机会,可能导致恶意程序的运行。当然这里并不是绝对说不执行这行代码就不会被恶意程序威胁,比如某些不法分子将恶意程序植入到知名App中,通过重签名在盗版网站提供用户下载。执行了sudo spctl --master-disable
这个命令的用户,应该都观察到安全性与隐私下面,有三种安装来源可供选择,分别是 App Store App Store与受信任的开发者 任何来源 从字面意思也可以看出其中的区别,那么我就从苹果证书机制的这一套说下如何实现。
3、苹果证书机制
对于Mac开发而言,有三种途径可供你选择发布你的App供用户来进行下载,不同的途径其加载原理也不相同,进而可能影响到电脑的安全。 申请App Store发布证书,提交到App Store审核通过后,用户就可以通过App Store来下载。 申请Developer证书,通过官网或者三方市场来发布 不申请证书,直接发布到官网或者第三方市场发布。
3.1 签名与证书
在用户A将一个文件发送给B,B如何得知这个文件没有被中途篡改呢?这就用到了非对称加密算法以及哈希算法。 非对称加密算法。签名中普遍使用的非对称加密算法是RSA算法,具体算法数学原理可以百度。简单来说就是RSA算法生成一个私钥和一个公钥,公钥加密的只有私钥才能解开,而私钥加密的公钥可以解开。一般私钥是保存在服务器后台,而公钥是分发到各个客户端主机上。 哈希算法。目前哈希算法比较常用的是MD5和sha256,可以将一段数据通过哈希算法生成固定长度的摘要数据,而且只要改动就能得到不同的摘要数据。 用户A生成一个私钥和一个公钥,将私钥自己保存,将公钥发布给用户B。A发送文件的时候,首先通过哈希算法计算文件的摘要,通过私钥加密后和文件A一起发送给用户B。用户B通过公钥进行解密,并将文件通过哈希算法生成摘要,如果相同则证明没有被改动过。 A用户生成的公钥分发给B,那么如何保证这个公钥没有被篡改呢?这就需要一个具有公信力的第三方机构做背书,将公钥和相关信息放在一份文件,并且使用第三方机构使用私钥对该文件摘要进行签名,这就是一个证书。从分发的安全性来说,只要第三方机构公钥通过其合法性,那么这个证书就是正确的。
3.2 什么是苹果证书
申请过苹果证书的同学应该都知道,需要在本地生成一对公私钥,这里我们将其备注为私钥L和公钥L。无论你申请的是发布证书还是开发证书(这里需要注意,Mac证书和ios还是有差异的,Mac提交App Store使用Third Patry开头的发布证书,而官网发布直接使用Developer证书即可)。然后将本地公钥上传到苹果证书制作中心,填入相应的信息,可以看到证书中含有我们使用私钥L对证书进行摘要加密,苹果即可以下载一个相应的证书。打开证书内容简介,刚生成的本地公钥L,SHA-256摘要以及其他信息。
3.3 Developer证书签名
在我们将证书导入到钥匙串后,我们在Xcode就可以选择这个证书为我们的项目来进行签名了。在Xcode中使用Build,便生成了目标的App。显示App包内容后,_CodeSignature文件夹下CodeResources文件完整记录了所有插件和资源的通过私钥加密后的摘要。那么这里的加密后的摘要使用的哪个私钥进行加密的呢,就是我们刚刚本地生成的私钥L。 当用户下载我们的app到主机上后,苹果如何进行验证呢?为了检查插件和资源没有被更改,需要依次检查每个资源的加密摘要。我们知道CodeResources是使用开发者私钥L进行加密的,要使用公钥L才能进行解密。那么这个公钥L客户端如何获取呢?我们检查App包下没有,发现苹果没有将证书直接携带在里面。通过查阅资料,发现证书及MachO相关摘要携带在其中。在网上搜索到一个好用的工具jtool,可以直接获取Macho文件中的证书信息,以下为随机在本地App中截取到的一段。
CA: Apple Certification Authority CN: Apple Root CA
CA: Apple Certification Authority CN: Apple Root CA Time: 190806010312Z CN: Developer ID Certification Authority
CA: Apple Certification Authority CN: Developer ID Application: Google, Inc. (EQHXZ8M8AV)
CA: EQHXZ8M8AV CN: Developer ID Certification Authority
CA: Apple Certification Authority CN: Apple Timestamp Certification Authority
CA: Apple Certification Authority CN: Timestamp Signer NWK1
CA: Apple Certification Authority CN: Apple Root CA CN: Apple Timestamp Certification Authority
CA: Apple Certification Authority CA: Apple Certification Authority CN: Apple Root CA
CA: Apple Certification Authority CN: Apple Root CA Time: 190806010312Z
可以发现完整的记录了证书连(证书链这里不展开了,不了解可以百度阅读),通过证书链获取苹果公钥A来验证获取到公钥L是合法的。如果是合法的即可验证CodeResources中资源是没有被篡改的。同时我们还可以从这个工具总看到以下内容(截取部分)。
Slot 43 (File page @0x2b000): bdc69882c7d1cb90f7a5dcf17d68e6d0cef6b5a86df0549108eae6c039aeb907 (OK)
Slot 44 (File page @0x2c000): d8d56266f0679d80fe0dbf3f2e61f5c8c84a0c57c2c0ab7c02b97ba5df65264d (OK)
Slot 45 (File page @0x2d000): 4c2f506e558909d95a89209ea5d754b72b785609b641138ce7dd65c483bff5b7 (OK)
Slot 46 (File page @0x2e000): 5ccca463e5f334e49e1a89f5f12c65835baaad733b3ebc520b3c7bce0a5fd532 (OK)
可以发现每一页都有一个加密摘要,在Macho二进制文件被实际加入到内存的时候,发生缺页异常,操作系统负责来进行验证,如果发现摘要不合法,就会杀死改进程。通过以上,可以发现App使用了官方的证书签名,将不会被存在被恶意程序利用的可能。但是这里的前提是官方的签名证书,作为普通用户,无法进行识别,App是否被重签名,这个后面再说。 3.4 AppStore证书签名 为什么说从苹果App Store下载的App一定是安全的,沙盒只是其中一方面,本质的原因是当开发者将自己的App上传到AppStore后,这个程序将会在苹果重新签名,只要保证证书是苹果的,那么一定是安全的。那么热如何来进行证明苹果是这么做的呢,我们通过jtool打印Tencent Lemon Lite的签名信息:
CA: Apple Certification Authority CN: Apple Root CA
CA: Apple Worldwide Developer Relations CN: Apple Worldwide Developer Relations Certification Authority
CA: Apple Certification Authority CN: Apple Root CA
CA: Apple Certification Authority CN: Apple Root CA
我们可以发现,证书已经全部换做是苹果的证书,所以AppStore可以完全保证App的安全,不被不法分子窜改。
3.5 kext驱动的签名和加载
很多VPN软件或者网络限速软件都使用到了驱动来进行完成。我们知道驱动运行Ring0,拥有内核的权限,完全可以做到任何破坏性的事情。在10.14.5之前,没有进行签名的Kext是不能加载运行的,除非用户关闭了SIP权限。如果要关闭SIP权限,需要在Recovery模式下执行以下代码 cstutil disable 来关闭系统保护,如果恶意驱动被加载,那么系统将会直接暴露在恶意程序面前,操作系统将失去保护能力。所以用户在关闭SIP权限时候一定要慎重。其次,kext驱动签名资格非常难申请,不是随便就可以申请下来,基本给的回复都是不具备内核开发能力。在这里我们可以看到,苹果的签名机制可以有效防止非法驱动加载。那么可能有疑问,驱动不可以被改造重签名吗?前面已经说过能申请到驱动开发证书的本就不多,而且证书有着公司的完整信息,从这方面说基本是安全的。
4、苹果公证服务
只要用户系统设置不选择任何来源以及关闭SIP权限情况下,安装AppStore软件或者安装驱动都是安全的,唯独受信任的开发者可能遭遇到重签名从而被恶意利用。那么苹果对此毫无办法吗,那么在10.15系统上苹果致力于解决这样的事情,这就是我将要说的苹果公证服务。在10.15上,开发者需要将自己的App传送到苹果公证中心,验证通过后会生成一个ticket。用户在下载我们的App时或者安装驱动,没有公证过的将无法安装。10.14.5和10.14.6在安装时会有黄色感叹号,说明这个就是没有公证的App。 那么为什么经过苹果公证服务的App就会更加安全呢?开发者将App传送到苹果公证服务器,第一步是需要绑定的账户以及对应的bundleid,其次会对整个App的权限设置做扫描,同时会对整个代码进行扫描是否有恶意代码等等。这样就最大程度保证了App的安全,同时也保证了App被篡改的难度。 那么这里非法分子是否可以使用自己的账号来对篡改后重签名的App来进行公证呢?因为BundleId是唯一的,所以他不可能申请到相同的bundleId来进行公证。那么是否对篡改后的app进行修改bundleId呢,首先从原理上是可以实现的。但是这就要依赖于苹果公证服务后面会越来越完善,对恶意代码扫描以及恶意账号的查封力度加大。但是本身这是一次巨大的进步,有效的对恶意App的拦截,保护了用户不被恶意程序的威胁。
5、总结
通过以上的结论,在10.14.5及以后,只要不关闭SIP权限以及软件来源不设置为任何来源,基本上最大程度都是安全的。其次,对于某些App索要管理员权限也需要慎重,一旦恶意程序获取到管理员权限,那么我们的电脑将会暴露在恶意程序面前。 最后Lemon已经通过Apple公证服务,可以放心安全的在官网下载使用。同时我们也有AppStore版本,欢迎下载使用。
~ 欢迎大家加入我们的知识星球,一起交流学习 ~
微信扫码加入:
点击链接加入:https://t.zsxq.com/n27YzRV