引子
这篇文章的来由,是因为公众号粉丝的一条私信。这位粉丝想让笔者剖析安全漏洞更多的规律性认识,与社会的关系,与其他学科理论的联系。再赶上最近安全圈又出了太多的奇葩政策、安全事件和厂商白帽子纠纷...于是诞生了这么一篇文章。
既然是安全漏洞的终极秘密「进阶篇」,那么我们就不能再说“熵”这些老套的东西了,那笔者就描述一些进阶的内容…
本文“长达”三千多字,希望读者可以耐心下翻读完。笔者将从历史、操控、对抗和未来四个部分描述安全漏洞的一些进阶秘密,每一部分的信息足够扩展出一个体系,希望能给读者带来启发,也许笔者来了兴趣还会有「终极篇」。
历史
你也许知道比尔盖茨,但你永远不会注意到巨人背后的核心技术人员。
拉里.奥斯特曼(Larry Osterman),微软首席软件设计工程师,从1984年8月开始在微软工作,至今仍在写代码活跃,已经整整从业快38 年...
拉里.奥斯特曼(Larry Osterman)
这位令人尊敬的大师曾在博客中调侃了很多微软的内部秘密,比如防御性编程的坑。
笔者上周拿Confluence 0day为例,简单科普了防御性编程,安全人员普遍认为厂商不懂安全,开发人员不懂安全。而拉里.奥斯特曼(Larry Osterman)这样的传奇大师,在玩rootkit和挖安全漏洞时,今天的很多安全人员还没有出生,然而懂安全漏洞并不妨碍这位大师成为微软幕后真正的技术首席,一直到今天还在岗位上。
来看看大师在18年前对于编程容错的认知:
参考:
https://docs.microsoft.com/en-us/archive/blogs/larryosterman/erroneous-assumptions
有没有人注意到所有的 Win32 文档对于每个 API 都有这样的内容:
返回值
如果函数成功,则返回值为 NO_ERROR。
如果函数失败,则返回以下的错误码之一。
值
| 描述 |
ERROR_INVALID_PARAMETER | 关于ERROR_INVALID_PARAMETER 错误的一些信息 |
Other | WinError.h 中定义的系统错误代码
|
无法想像有多少人抱怨过对上述返回值的描述,微软究竟为什么不能在文档中直接枚举所有的错误码?他们是傻,还是怎么着了?
其实答案要简单一些。过去我们已经被这样的事情坑了,我们不愿意再次被坑。
我桌上的纪念品中有本MS-DOS 2.0参考手册,微软于1984年出版。在第1-143页,有个创建句柄的API,这是DOS版的open()函数。该API文档枚举了当时所有的错误码
AX可取值有:
3 = 找不到路径
4 = 打开的文件太多
5 = 拒绝访问
微软和IBM公布了所有DOS调用的所有返回值信息,我们跟客户说,INT 21的0x3D号调用只有三种返回值(3、4、5)。你知道吗,客户相信我们,他们基于这个说法开发应用程序。
好吧,随之而来的是DOS 3.1,它增加了对网络的支持,于是新增了一些失败原因,比如,"未找到网络路径"(文件在服务器上但服务器下线了),"共享冲突"(有人以排他方式打开了一个共享文件,导致他人打开失败)。
起初DOS 3.1通过AX返回新的错误码。微软以为绝大多数程序员足够聪明,知道将来会出现3、4、5之外的新的错误码。
我们开始测试DOS 3.1的兼容性,发现这个假设大错特错。已有的应用程序左崩崩、右崩崩,每个被测应用都崩了。为啥?因为微软和IBM告诉这些应用的开发者,他们只会得到3、4、5三种错误码。当年内存非常昂贵,他们不想编写容错性更强的代码,那样太费内存。当你的应用跑在64KB内存的主机上时,防御性编程只是可选项。
为了保持向后兼容性,微软只好为DOS 3.1设计一种称为"DOS错误映射表"的技术,它将一个更广范围的错误码通过N对3映射到DOS 2.0的3种错误码中。为了获取更精准的新错误码,应用可以额外调用一个新的API(Get Extended Error)。
这项技术仍然存在于Longhorn中,我前几天还去查看了一下源码,在NTVDM相关组件中,不在Win32组件中。不管怎么样,它还活着,而且很可能我们永远无法摆脱它。至少在我们丢弃对16位DOS的支持之前,我们无法摆脱它,这不会很快发生。
从此,微软再也不文档化API返回值的所有错误码,由此将处理潜在出现新错误码的责任从微软转嫁给应用开发人员自己。
微软早在十几年前的经验就告诉我们,软件工程的潜在错误是不可能穷尽的,在笔者看来,安全漏洞也是软件工程潜在错误的一种,它会一直存在并且永远都会存在。
操控
有一位心灵魔术师叫达伦布朗,别的魔术师能予人惊喜,而他带来的却是恐惧。操控人心对他来说是家常便饭。如果他想的话,只要告诉你“水是热的”,你就会在冰水里面躺一天,直至冻死。
曾经他表演过多个细思恐极的魔术,最出名的,还要属“俄罗斯轮盘赌”。
具体流程是这样的:观众在左轮手枪6个弹位里,随机放入一颗子弹。之后从1至6依次念出6个数字,达伦布朗再通过观众的声音决定扣动扳机的时刻。
这还不是最震撼人心的,他的魔术涉及很多心理操控原理,魔术效果令人发指,如操控一个普通人变成杀人犯的魔术实验秀,有兴趣的同学可以去看看整个完整的魔术真人秀实验。这个魔术秀的原理是利用了“社会屈从性”。社会屈从性指:人在社会权威的框架下,被影响做出一系列有违自身三观和人格的行为,从而获取社会认同和安全感。
例如其中一个实验:布朗首先找了三个托,这三个托会根据有规律的铃声做出坐下或起立的动作。
之后,不知情的实验者依次入场,因为“社会屈从性”,很多人会做出跟演员一样的动作。
这个例子只是让读者理解“社会屈从性”的原理。在安全领域的类似操控,是超出普通人想象的,由于安全漏洞产生于软件的开发过程,软件是由人开发,人是社会性动物,不能脱离群体而独居,自然也会受到“社会屈从性”的影响。例如:双椭圆曲线确定性随机比特生成器 (Dual Elliptic Curve Deterministic Random Bit Generator),Dual_EC_DRBG是被美国国家安全局(NSA)控制创造的一种使用椭圆曲线密码学实现的密码学安全伪随机生成器(CSPRNG)。Dual_EC_DRBG曾是NIST SP 800-90A(美国安全标准制定机构)定义的4个(现为3个,Dual_EC_DRBG已经被确认为刻意的后门)标准的CSPRNG之一,被业界视为标准,推荐使用。2007年,微软公司的研究人员发表了一篇技术论文,警告说NSA的加密算法Dual_EC_DRBG可能包含一个后门。研究人员专注于一种叫做“Q值”的东西,这是算法中用来帮助创建加密密钥的一个很大的数字。当时,NSA 有一个它推荐的特定值。据研究人员称,选择使用这个值的人,可以计算这些密钥的秘密内容并最终解密通信。 2008年,Juniper(著名网络防火墙供应商)曾在其NetScreen设备中使用了NSA创造的“Dual Elliptic Curve Deterministic Random Bit Generator ”算法,尽管该公司的工程师知道该算法可能是被安全专家讨论的后门漏洞,但仍然使用该加密算法开发安全功能,因为该公司早期更愿意相信业界的安全标准并依据标准进行开发,这已经是一种行业惯例。
普通民众很难想象这样的故事,会有那么邪恶的黑客去制造并引导程序员使用一种有漏洞的加密算法,用“社会屈从性”原理在安全产品中植入漏洞,这事已经是常态,NSA就敢这样明目张胆的干。当然,关于信息安全领域的操控,还有很多超出常人理解的手段,由于太过高端和邪恶,这里笔者就不详述了。笔者曾提到过安全的意义在于对抗,如果没有对抗,说明你的业务或产品本身就不受欢迎,并不是成功的业务或产品。安全漏洞的不断修复,直至最终产生安全弹性,这也是业务或产品圆满的过程。这些是积极的一面,但笔者更喜欢对抗失败的案例,因为可以学到更多 。拿国内的项目,举一个失败例子: Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。阿里有一个叫FastJson的项目,是阿里巴巴的开源库,用于对JSON格式的数据进行解析和打包。简单说,这是个处理JSON格式的数据工件库,将JSON数据转换成一个类,或者是将一个类转换成一段JSON数据的基础库。然而不幸的是,Fastjson在JSON数据的处理过程中引入了AutoType特性,这个功能特性在设计之初考虑安全问题不够周全,给后续Fastjson的使用者带来了无尽的痛苦(也养活了安全圈一大波人),因为这个特性给整个项目施加了数据可以变为代码执行的魔咒~这个项目的补丁历史不用笔者多介绍了,所有人都耳熟能详,它的漏洞修复对抗史就是一部多年的血泪史,每一次漏洞的攻破和每一次漏洞的修复,是黑客与开发者之间见血的刺刀对抗,这个过程持续了2年以上。在对抗的中间过程,发生了戏剧性的一幕,开发者将黑白名单这种防御编程机制升级为了字符串加密后的哈希列表碰撞,试图隐藏黑白名单。说实话,笔者当时看到这个举动颇为懵逼,无法想象开发者当时加入这个机制的心情,大概是开发者被黑客毒打,感受到了世界深深的恶意,开始不相信“爱”了。笔者感受到了代码中间的深深怒意,仿佛听见了来自开发者那里:“你是黑客~你全家都是黑客”的心声。Fastjson项目第一次将黑白名单机制变成哈希值碰撞这个案例最终并没有那么快完结,因为最近Fastjson的白名单机制中又闹出了0day漏洞(细节就不详述了),阿里借此发布了个新的fastjson2。笔者看了下发布声明,发现开发者承认自己的白名单处理有疏漏,并且觉悟到了白名单加不好也会变成“后门”,现在大概只相信黑名单了~并且官方还含蓄的告诉大家,黑名单机制也不能保证绝对安全,字里行间可以感受到开发者的无奈妥协加沮丧。https://github.com/alibaba/fastjson2/wiki/fastjson2_autotype_cn未来代表了未知,没有人可以完美预见未来,未来的可能性太多。无论你是甲方还是乙方,不管你是牛B哄哄的黑客大师,还是刚入门的萌新,对于安全漏洞请心存敬畏,因为它可能是你我在未来都无法预见的错误。同时,我们要学会与开发人员共情,体会写代码的不易,不要为了几个破安全漏洞、几块赏金和所谓的虚名荣誉,去争个头破血流。保持好奇心,发现问题,看到问题,不制造问题,去解决问题,这才是真正的黑客普世价值观。最后,笔者认为,建设远比破坏困难, 简单发现安全问题,却无法解决安全问题,其实也是无用的。如果你关注它,却不能参与建设它,安全漏洞这些过程,只不过是一个治标不治本的过程。对于安全漏洞,处理它的过程公开透明才是最重要的,也许这正是开源软件社区能够繁荣推进的真正原因...有的,放开一切的杂念去赞美虚空中的“神”(意识形态),这不是宗教崇拜信仰,而是顶礼膜拜宇宙虚空中那种不可名状的伟大。Shiva的另一个意思叫做虚无,宇宙的毁灭是一切归为虚无,那么一切皆为湿婆。
在无尽的虚无湿婆之中,然后出现能够创造一切的Shakti(萨克蒂),宇宙由此再次诞生。
Vishnu(毗湿奴)维持世界的一切美意,Brahma(梵天)创造世界与生命。
一切是萨克蒂始,湿婆…